Beispiel #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;
                }
            }
        }
Beispiel #2
0
        private DirectoryEntry AddFileToDirectory(File file, Directory dir, string name, NewFileOptions options)
        {
            DirectoryEntry entry;

            bool createShortNames;
            if (options != null && options.CreateShortNames.HasValue)
            {
                createShortNames = options.CreateShortNames.Value;
            }
            else
            {
                createShortNames = CreateShortNames;
            }

            if (createShortNames)
            {
                if (Utilities.Is8Dot3(name.ToUpperInvariant()))
                {
                    entry = dir.AddEntry(file, name, FileNameNamespace.Win32AndDos);
                }
                else
                {
                    entry = dir.AddEntry(file, name, FileNameNamespace.Win32);
                    dir.AddEntry(file, dir.CreateShortName(name), FileNameNamespace.Dos);
                }
            }
            else
            {
                entry = dir.AddEntry(file, name, FileNameNamespace.Posix);
            }

            return entry;
        }
Beispiel #3
0
        /// <summary>
        /// Creates a directory.
        /// </summary>
        /// <param name="path">The path of the new directory.</param>
        /// <param name="options">Options controlling attributes of the new Director, or <c>null</c> for defaults.</param>
        public void CreateDirectory(string path, NewFileOptions options)
        {
            using (new NtfsTransaction())
            {
                string[] pathElements = path.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries);

                Directory focusDir = GetDirectory(MasterFileTable.RootDirIndex);
                DirectoryEntry focusDirEntry = focusDir.DirectoryEntry;

                for (int i = 0; i < pathElements.Length; ++i)
                {
                    DirectoryEntry childDirEntry = focusDir.GetEntryByName(pathElements[i]);
                    if (childDirEntry == null)
                    {
                        FileAttributeFlags newDirAttrs = focusDir.StandardInformation.FileAttributes;
                        if (options != null && options.Compressed.HasValue)
                        {
                            if (options.Compressed.Value)
                            {
                                newDirAttrs |= FileAttributeFlags.Compressed;
                            }
                            else
                            {
                                newDirAttrs &= ~FileAttributeFlags.Compressed;
                            }
                        }

                        Directory childDir = Directory.CreateNew(_context, newDirAttrs);
                        try
                        {
                            childDirEntry = AddFileToDirectory(childDir, focusDir, pathElements[i], options);

                            RawSecurityDescriptor parentSd = DoGetSecurity(focusDir);
                            RawSecurityDescriptor newSd;
                            if (options != null && options.SecurityDescriptor != null)
                            {
                                newSd = options.SecurityDescriptor;
                            }
                            else
                            {
                                newSd = SecurityDescriptor.CalcNewObjectDescriptor(parentSd, false);
                            }

                            DoSetSecurity(childDir, newSd);
                            childDirEntry.UpdateFrom(childDir);

                            // Update the directory entry by which we found the directory we've just modified
                            focusDirEntry.UpdateFrom(focusDir);

                            focusDir = childDir;
                        }
                        finally
                        {
                            if (childDir.HardLinkCount == 0)
                            {
                                childDir.Delete();
                            }
                        }
                    }
                    else
                    {
                        focusDir = GetDirectory(childDirEntry.Reference);
                    }

                    focusDirEntry = childDirEntry;
                }
            }
        }
Beispiel #4
0
        private DirectoryEntry CreateNewFile(string path, NewFileOptions options)
        {
            DirectoryEntry result;
            DirectoryEntry parentDirEntry = GetDirectoryEntry(Utilities.GetDirectoryFromPath(path));
            Directory parentDir = GetDirectory(parentDirEntry.Reference);

            FileAttributeFlags newFileAttrs = parentDir.StandardInformation.FileAttributes;
            if (options != null && options.Compressed.HasValue)
            {
                if (options.Compressed.Value)
                {
                    newFileAttrs |= FileAttributeFlags.Compressed;
                }
                else
                {
                    newFileAttrs &= ~FileAttributeFlags.Compressed;
                }
            }

            File file = File.CreateNew(_context, newFileAttrs);
            try
            {
                result = AddFileToDirectory(file, parentDir, Utilities.GetFileFromPath(path), options);

                RawSecurityDescriptor parentSd = DoGetSecurity(parentDir);
                RawSecurityDescriptor newSd;
                if (options != null && options.SecurityDescriptor != null)
                {
                    newSd = options.SecurityDescriptor;
                }
                else
                {
                    newSd = SecurityDescriptor.CalcNewObjectDescriptor(parentSd, false);
                }

                DoSetSecurity(file, newSd);
                result.UpdateFrom(file);

                parentDirEntry.UpdateFrom(parentDir);
            }
            finally
            {
                if (file.HardLinkCount == 0)
                {
                    file.Delete();
                }
            }

            return result;
        }