Пример #1
0
        public override Int32 Open(
            String FileName,
            UInt32 CreateOptions,
            UInt32 GrantedAccess,
            out Object FileNode0,
            out Object FileDesc,
            out FileInfo FileInfo,
            out String NormalizedName)
        {
            FileNode0      = default(Object);
            FileDesc       = default(Object);
            FileInfo       = default(FileInfo);
            NormalizedName = default(String);

            FileNode FileNode;
            Int32    Result;

            FileNode = FileNodeMap.Get(FileName);
            if (null == FileNode)
            {
                Result = STATUS_OBJECT_NAME_NOT_FOUND;
                FileNodeMap.GetParent(FileName, ref Result);
                return(Result);
            }

            Interlocked.Increment(ref FileNode.OpenCount);
            FileNode0      = FileNode;
            FileInfo       = FileNode.GetFileInfo();
            NormalizedName = FileNode.FileName;

            return(STATUS_SUCCESS);
        }
Пример #2
0
        public override int GetDirInfoByName(
            Object ParentNode0,
            Object FileDesc,
            String FileName,
            out String NormalizedName,
            out FileInfo FileInfo)
        {
            FileNode ParentNode = (FileNode)ParentNode0;
            FileNode FileNode;

            FileName =
                ParentNode.FileName +
                ("\\" == ParentNode.FileName ? "" : "\\") +
                Path.GetFileName(FileName);

            FileNode = FileNodeMap.Get(FileName);
            if (null == FileNode)
            {
                NormalizedName = default(String);
                FileInfo       = default(FileInfo);
                return(STATUS_OBJECT_NAME_NOT_FOUND);
            }

            NormalizedName = Path.GetFileName(FileNode.FileName);
            FileInfo       = FileNode.FileInfo;

            return(STATUS_SUCCESS);
        }
Пример #3
0
        public override void Cleanup(
            Object FileNode0,
            Object FileDesc,
            String FileName,
            UInt32 Flags)
        {
            FileNode FileNode     = (FileNode)FileNode0;
            FileNode MainFileNode = null != FileNode.MainFileNode ?
                                    FileNode.MainFileNode : FileNode;

            if (0 != (Flags & CleanupSetArchiveBit))
            {
                if (0 == (MainFileNode.FileInfo.FileAttributes & (UInt32)FileAttributes.Directory))
                {
                    MainFileNode.FileInfo.FileAttributes |= (UInt32)FileAttributes.Archive;
                }
            }

            if (0 != (Flags & (CleanupSetLastAccessTime | CleanupSetLastWriteTime | CleanupSetChangeTime)))
            {
                UInt64 SystemTime = (UInt64)DateTime.Now.ToFileTimeUtc();

                if (0 != (Flags & CleanupSetLastAccessTime))
                {
                    MainFileNode.FileInfo.LastAccessTime = SystemTime;
                }
                if (0 != (Flags & CleanupSetLastWriteTime))
                {
                    MainFileNode.FileInfo.LastWriteTime = SystemTime;
                }
                if (0 != (Flags & CleanupSetChangeTime))
                {
                    MainFileNode.FileInfo.ChangeTime = SystemTime;
                }
            }

            if (0 != (Flags & CleanupSetAllocationSize))
            {
                UInt64 AllocationUnit = MEMFS_SECTOR_SIZE * MEMFS_SECTORS_PER_ALLOCATION_UNIT;
                UInt64 AllocationSize = (FileNode.FileInfo.FileSize + AllocationUnit - 1) /
                                        AllocationUnit * AllocationUnit;
                SetFileSizeInternal(FileNode, AllocationSize, true);
            }

            if (0 != (Flags & CleanupDelete) && !FileNodeMap.HasChild(FileNode))
            {
                List <String> StreamFileNames = new List <String>(FileNodeMap.GetStreamFileNames(FileNode));
                foreach (String StreamFileName in StreamFileNames)
                {
                    FileNode StreamNode = FileNodeMap.Get(StreamFileName);
                    if (null == StreamNode)
                    {
                        continue; /* should not happen */
                    }
                    FileNodeMap.Remove(StreamNode);
                }
                FileNodeMap.Remove(FileNode);
            }
        }
Пример #4
0
        public override Boolean GetStreamEntry(
            Object FileNode0,
            Object FileDesc,
            ref Object Context,
            out String StreamName,
            out UInt64 StreamSize,
            out UInt64 StreamAllocationSize)
        {
            FileNode             FileNode   = (FileNode)FileNode0;
            IEnumerator <String> Enumerator = (IEnumerator <String>)Context;

            if (null == Enumerator)
            {
                if (null != FileNode.MainFileNode)
                {
                    FileNode = FileNode.MainFileNode;
                }

                List <String> StreamFileNames = new List <String>();
                if (0 == (FileNode.FileInfo.FileAttributes & (UInt32)FileAttributes.Directory))
                {
                    StreamFileNames.Add(FileNode.FileName);
                }
                StreamFileNames.AddRange(FileNodeMap.GetStreamFileNames(FileNode));
                Context = Enumerator = StreamFileNames.GetEnumerator();
            }

            while (Enumerator.MoveNext())
            {
                String   FullFileName   = Enumerator.Current;
                FileNode StreamFileNode = FileNodeMap.Get(FullFileName);
                if (null != StreamFileNode)
                {
                    int Index = FullFileName.IndexOf(':');
                    if (0 > Index)
                    {
                        StreamName = "";
                    }
                    else
                    {
                        StreamName = FullFileName.Substring(Index + 1);
                    }
                    StreamSize           = StreamFileNode.FileInfo.FileSize;
                    StreamAllocationSize = StreamFileNode.FileInfo.AllocationSize;
                    return(true);
                }
            }

            StreamName           = default(String);
            StreamSize           = default(UInt64);
            StreamAllocationSize = default(UInt64);
            return(false);
        }
Пример #5
0
        public override Int32 Overwrite(
            Object FileNode0,
            Object FileDesc,
            UInt32 FileAttributes,
            Boolean ReplaceFileAttributes,
            UInt64 AllocationSize,
            out FileInfo FileInfo)
        {
            FileInfo = default(FileInfo);

            FileNode FileNode = (FileNode)FileNode0;
            Int32    Result;

            List <String> StreamFileNames = new List <String>(FileNodeMap.GetStreamFileNames(FileNode));

            foreach (String StreamFileName in StreamFileNames)
            {
                FileNode StreamNode = FileNodeMap.Get(StreamFileName);
                if (null == StreamNode)
                {
                    continue; /* should not happen */
                }
                if (0 == StreamNode.OpenCount)
                {
                    FileNodeMap.Remove(StreamNode);
                }
            }

            Result = SetFileSizeInternal(FileNode, AllocationSize, true);
            if (0 > Result)
            {
                return(Result);
            }
            if (ReplaceFileAttributes)
            {
                FileNode.FileInfo.FileAttributes = FileAttributes | (UInt32)System.IO.FileAttributes.Archive;
            }
            else
            {
                FileNode.FileInfo.FileAttributes |= FileAttributes | (UInt32)System.IO.FileAttributes.Archive;
            }
            FileNode.FileInfo.FileSize           = 0;
            FileNode.FileInfo.LastAccessTime     =
                FileNode.FileInfo.LastWriteTime  =
                    FileNode.FileInfo.ChangeTime = (UInt64)DateTime.Now.ToFileTimeUtc();

            FileInfo = FileNode.GetFileInfo();

            return(STATUS_SUCCESS);
        }
Пример #6
0
        public override Int32 Rename(
            Object FileNode0,
            Object FileDesc,
            String FileName,
            String NewFileName,
            Boolean ReplaceIfExists)
        {
            FileNode FileNode = (FileNode)FileNode0;
            FileNode NewFileNode;

            NewFileNode = FileNodeMap.Get(NewFileName);
            if (null != NewFileNode && FileNode != NewFileNode)
            {
                if (!ReplaceIfExists)
                {
                    return(STATUS_OBJECT_NAME_COLLISION);
                }
                if (0 != (NewFileNode.FileInfo.FileAttributes & (UInt32)FileAttributes.Directory))
                {
                    return(STATUS_ACCESS_DENIED);
                }
            }

            if (null != NewFileNode && FileNode != NewFileNode)
            {
                FileNodeMap.Remove(NewFileNode);
            }

            List <String> DescendantFileNames = new List <String>(FileNodeMap.GetDescendantFileNames(FileNode));

            foreach (String DescendantFileName in DescendantFileNames)
            {
                FileNode DescendantFileNode = FileNodeMap.Get(DescendantFileName);
                if (null == DescendantFileNode)
                {
                    continue; /* should not happen */
                }
                FileNodeMap.Remove(DescendantFileNode);
                DescendantFileNode.FileName =
                    NewFileName + DescendantFileNode.FileName.Substring(FileName.Length);
                FileNodeMap.Insert(DescendantFileNode);
            }

            return(STATUS_SUCCESS);
        }
Пример #7
0
        public override Int32 GetReparsePointByName(
            String FileName,
            Boolean IsDirectory,
            ref Byte[] ReparseData)
        {
            FileNode FileNode;

            FileNode = FileNodeMap.Get(FileName);
            if (null == FileNode)
            {
                return(STATUS_OBJECT_NAME_NOT_FOUND);
            }

            if (0 == (FileNode.FileInfo.FileAttributes & (UInt32)FileAttributes.ReparsePoint))
            {
                return(STATUS_NOT_A_REPARSE_POINT);
            }

            ReparseData = FileNode.ReparseData;

            return(STATUS_SUCCESS);
        }
Пример #8
0
        public override Int32 GetSecurityByName(
            String FileName,
            out UInt32 FileAttributes /* or ReparsePointIndex */,
            ref Byte[] SecurityDescriptor)
        {
            FileNode FileNode = FileNodeMap.Get(FileName);

            if (null == FileNode)
            {
                Int32 Result = STATUS_OBJECT_NAME_NOT_FOUND;
                if (FindReparsePoint(FileName, out FileAttributes))
                {
                    Result = STATUS_REPARSE;
                }
                else
                {
                    FileNodeMap.GetParent(FileName, ref Result);
                }
                return(Result);
            }

            UInt32 FileAttributesMask = ~(UInt32)0;

            if (null != FileNode.MainFileNode)
            {
                FileAttributesMask = ~(UInt32)System.IO.FileAttributes.Directory;
                FileNode           = FileNode.MainFileNode;
            }
            FileAttributes = FileNode.FileInfo.FileAttributes & FileAttributesMask;
            if (null != SecurityDescriptor)
            {
                SecurityDescriptor = FileNode.FileSecurity;
            }

            return(STATUS_SUCCESS);
        }
Пример #9
0
        public override Boolean ReadDirectoryEntry(
            Object FileNode0,
            Object FileDesc,
            String Pattern,
            String Marker,
            ref Object Context,
            out String FileName,
            out FileInfo FileInfo)
        {
            FileNode             FileNode   = (FileNode)FileNode0;
            IEnumerator <String> Enumerator = (IEnumerator <String>)Context;

            if (null == Enumerator)
            {
                List <String> ChildrenFileNames = new List <String>();
                if ("\\" != FileNode.FileName)
                {
                    /* if this is not the root directory add the dot entries */
                    if (null == Marker)
                    {
                        ChildrenFileNames.Add(".");
                    }
                    if (null == Marker || "." == Marker)
                    {
                        ChildrenFileNames.Add("..");
                    }
                }
                ChildrenFileNames.AddRange(FileNodeMap.GetChildrenFileNames(FileNode,
                                                                            "." != Marker && ".." != Marker ? Marker : null));
                Context = Enumerator = ChildrenFileNames.GetEnumerator();
            }

            while (Enumerator.MoveNext())
            {
                String FullFileName = Enumerator.Current;
                if ("." == FullFileName)
                {
                    FileName = ".";
                    FileInfo = FileNode.GetFileInfo();
                    return(true);
                }
                else if (".." == FullFileName)
                {
                    Int32    Result     = STATUS_SUCCESS;
                    FileNode ParentNode = FileNodeMap.GetParent(FileNode.FileName, ref Result);
                    if (null != ParentNode)
                    {
                        FileName = "..";
                        FileInfo = ParentNode.GetFileInfo();
                        return(true);
                    }
                }
                else
                {
                    FileNode ChildFileNode = FileNodeMap.Get(FullFileName);
                    if (null != ChildFileNode)
                    {
                        FileName = Path.GetFileName(FullFileName);
                        FileInfo = ChildFileNode.GetFileInfo();
                        return(true);
                    }
                }
            }

            FileName = default(String);
            FileInfo = default(FileInfo);
            return(false);
        }
Пример #10
0
        public override Int32 Create(
            String FileName,
            UInt32 CreateOptions,
            UInt32 GrantedAccess,
            UInt32 FileAttributes,
            Byte[] SecurityDescriptor,
            UInt64 AllocationSize,
            out Object FileNode0,
            out Object FileDesc,
            out FileInfo FileInfo,
            out String NormalizedName)
        {
            FileNode0      = default(Object);
            FileDesc       = default(Object);
            FileInfo       = default(FileInfo);
            NormalizedName = default(String);

            FileNode FileNode;
            FileNode ParentNode;
            Int32    Result = STATUS_SUCCESS;

            FileNode = FileNodeMap.Get(FileName);
            if (null != FileNode)
            {
                return(STATUS_OBJECT_NAME_COLLISION);
            }
            ParentNode = FileNodeMap.GetParent(FileName, ref Result);
            if (null == ParentNode)
            {
                return(Result);
            }

            if (0 != (CreateOptions & FILE_DIRECTORY_FILE))
            {
                AllocationSize = 0;
            }
            if (FileNodeMap.Count() >= MaxFileNodes)
            {
                return(STATUS_CANNOT_MAKE);
            }
            if (AllocationSize > MaxFileSize)
            {
                return(STATUS_DISK_FULL);
            }

            if ("\\" != ParentNode.FileName)
            {
                /* normalize name */
                FileName = ParentNode.FileName + "\\" + Path.GetFileName(FileName);
            }
            FileNode = new FileNode(FileName);
            FileNode.MainFileNode            = FileNodeMap.GetMain(FileName);
            FileNode.FileInfo.FileAttributes = 0 != (FileAttributes & (UInt32)System.IO.FileAttributes.Directory) ?
                                               FileAttributes : FileAttributes | (UInt32)System.IO.FileAttributes.Archive;
            FileNode.FileSecurity = SecurityDescriptor;
            if (0 != AllocationSize)
            {
                Result = SetFileSizeInternal(FileNode, AllocationSize, true);
                if (0 > Result)
                {
                    return(Result);
                }
            }
            FileNodeMap.Insert(FileNode);

            Interlocked.Increment(ref FileNode.OpenCount);
            FileNode0      = FileNode;
            FileInfo       = FileNode.GetFileInfo();
            NormalizedName = FileNode.FileName;

            return(STATUS_SUCCESS);
        }