예제 #1
0
        /// <summary>
        /// Opens the specified file.
        /// </summary>
        /// <param name="path">The full path of the file to open.</param>
        /// <param name="mode">The file mode for the created stream.</param>
        /// <param name="access">The access permissions for the returned stream.</param>
        /// <param name="options">Options controlling attributes of a new file, or <c>null</c> for defaults (ignored if file exists).</param>
        /// <returns>The new stream.</returns>
        public SparseStream OpenFile(string path, FileMode mode, FileAccess access, NewFileOptions options)
        {
            using (new NtfsTransaction())
            {
                string attributeName;
                AttributeType attributeType;
                string dirEntryPath = ParsePath(path, out attributeName, out attributeType);

                DirectoryEntry entry = GetDirectoryEntry(dirEntryPath);
                if (entry == null)
                {
                    if (mode == FileMode.Open)
                    {
                        throw new FileNotFoundException("No such file", path);
                    }
                    else
                    {
                        entry = CreateNewFile(dirEntryPath, options);
                    }
                }
                else if (mode == FileMode.CreateNew)
                {
                    throw new IOException("File already exists");
                }

                if ((entry.Details.FileAttributes & FileAttributes.Directory) != 0 && attributeType == AttributeType.Data)
                {
                    throw new IOException("Attempt to open directory as a file");
                }
                else
                {
                    File file = GetFile(entry.Reference);
                    NtfsStream ntfsStream = file.GetStream(attributeType, attributeName);

                    if (ntfsStream == null)
                    {
                        if (mode == FileMode.Create || mode == FileMode.OpenOrCreate)
                        {
                            ntfsStream = file.CreateStream(attributeType, attributeName);
                        }
                        else
                        {
                            throw new FileNotFoundException("No such attribute on file", path);
                        }
                    }

                    SparseStream stream = new NtfsFileStream(this, entry, attributeType, attributeName, access);

                    if (mode == FileMode.Create || mode == FileMode.Truncate)
                    {
                        stream.SetLength(0);
                    }

                    return stream;
                }
            }
        }
예제 #2
0
        /// <summary>
        /// Opens the specified file.
        /// </summary>
        /// <param name="path">The full path of the file to open.</param>
        /// <param name="mode">The file mode for the created stream.</param>
        /// <param name="access">The access permissions for the returned stream.</param>
        /// <returns>The new stream.</returns>
        public override Stream OpenFile(string path, FileMode mode, FileAccess access)
        {
            using (new NtfsTransaction())
            {
                string fileName = Utilities.GetFileFromPath(path);
                string attributeName = null;
                AttributeType attributeType = AttributeType.Data;

                string[] fileNameElements = fileName.Split(new char[]{':'}, 3);
                fileName = fileNameElements[0];

                if(fileNameElements.Length > 1)
                {
                    attributeName = fileNameElements[1];
                    if(string.IsNullOrEmpty(attributeName))
                    {
                        attributeName = null;
                    }
                }

                if(fileNameElements.Length > 2)
                {
                    string typeName = fileNameElements[2];
                    AttributeDefinitionRecord typeDefn = _context.AttributeDefinitions.Lookup(typeName);
                    if(typeDefn == null)
                    {
                        throw new FileNotFoundException(string.Format(CultureInfo.InvariantCulture, "No such attribute type '{0}'", typeName), path);
                    }

                    attributeType = typeDefn.Type;
                }

                string dirName;
                try
                {
                    dirName = Utilities.GetDirectoryFromPath(path);
                }
                catch (ArgumentException)
                {
                    throw new IOException("Invalid path: " + path);
                }

                string dirEntryPath;
                try
                {
                    dirEntryPath = Path.Combine(dirName, fileName);
                }
                catch (ArgumentException)
                {
                    throw new IOException("Invalid path: " + path);
                }

                DirectoryEntry entry = GetDirectoryEntry(dirEntryPath);
                if (entry == null)
                {
                    if (mode == FileMode.Open)
                    {
                        throw new FileNotFoundException("No such file", path);
                    }
                    else
                    {
                        File file = File.CreateNew(_context);
                        try
                        {
                            DirectoryEntry parentDirEntry = GetDirectoryEntry(Path.GetDirectoryName(path));
                            Directory parentDir = GetDirectory(parentDirEntry.Reference);
                            entry = AddFileToDirectory(file, parentDir, Path.GetFileName(path));

                            RawSecurityDescriptor sd = DoGetSecurity(parentDir);
                            DoSetSecurity(file, SecurityDescriptor.CalcNewObjectDescriptor(sd, false));
                            entry.UpdateFrom(file);

                            parentDirEntry.UpdateFrom(parentDir);
                        }
                        finally
                        {
                            if (file.HardLinkCount == 0)
                            {
                                file.Delete();
                            }
                        }
                    }
                }
                else if (mode == FileMode.CreateNew)
                {
                    throw new IOException("File already exists");
                }


                if ((entry.Details.FileAttributes & FileAttributes.Directory) != 0 && attributeType == AttributeType.Data)
                {
                    throw new IOException("Attempt to open directory as a file");
                }
                else
                {
                    File file = GetFile(entry.Reference);
                    NtfsStream ntfsStream = file.GetStream(attributeType, attributeName);

                    if (ntfsStream == null)
                    {
                        if (mode == FileMode.Create || mode == FileMode.OpenOrCreate)
                        {
                            ntfsStream = file.CreateStream(attributeType, attributeName);
                        }
                        else
                        {
                            throw new FileNotFoundException("No such attribute on file", path);
                        }
                    }

                    SparseStream stream = new NtfsFileStream(this, entry, attributeType, attributeName, access);

                    if (mode == FileMode.Create || mode == FileMode.Truncate)
                    {
                        stream.SetLength(0);
                    }

                    return stream;
                }
            }
        }