Beispiel #1
0
        public FileHandle Open()
        {
            lock (Lock) {
                if (_isOpen)
                {
                    throw new SharingException();
                }
                _fileIO = new Lazy <FileIO>(() => new FileIO(_fileSystem, _file));
                _isOpen = true;

                FileHandle h = Handles.CreateNewFileHandle(this);
                return(h);
            }
        }
Beispiel #2
0
 public static FileHandle CreateNewFileHandle(DokanFile file)
 {
     lock (_handles) {
         for (int i = 0; i < _handles.Count; i++)
         {
             if (_handles[i] == null)
             {
                 FileHandle reusedHandle = new FileHandle(i, file);
                 _handles[i] = reusedHandle;
                 return(reusedHandle);
             }
         }
         FileHandle newHandle = new FileHandle(_handles.Count, file);
         _handles.Add(newHandle);
         return(newHandle);
     }
 }
Beispiel #3
0
        public NtStatus CreateFile(string fileName, DokanNet.FileAccess access, FileShare share, FileMode mode, FileOptions options, FileAttributes attributes,
                                   DokanFileInfo info)
        {
            lock (createFileLock) {
                try {
                    FileHandle fileHandle    = null;
                    bool       alreadyExists = false;

                    string           name            = null;
                    Directory        parentDirectory = null;
                    FileSystemObject fso             = _fileSystem.GetFileSystemObject(fileName);
                    if (fso == null)
                    {
                        parentDirectory = _fileSystem.GetParentDirectory(fileName, out name);
                        if (parentDirectory == null)
                        {
                            Console.WriteLine($"PATH NOT FOUND CreateFile(\"{fileName}\", {access}, {share}, {mode})");
                            return(DokanResult.PathNotFound);
                        }
                    }

                    if (fso is Directory)
                    {
                        info.IsDirectory = true;
                    }

                    if (info.IsDirectory)
                    {
                        Directory       directory = null;
                        DirectoryHandle handle    = null;

                        switch (mode)
                        {
                        case FileMode.CreateNew:
                            if (fso != null)
                            {
                                return(DokanResult.FileExists);
                            }

                            DirectoryHandle parent = null;
                            try {
                                parent    = Open(parentDirectory, FileAccess.GenericWrite, FileShare.ReadWrite);
                                directory = _fileSystem.CreateDirectory(parentDirectory, name);
                                handle    = Open(directory, access, share);

                                directory.Owner = WindowsIdentity.GetCurrent().User;
                                directory.Group = WindowsIdentity.GetCurrent().User;
                            } finally {
                                if (parent != null)
                                {
                                    parent.Close();
                                    Handles.DeleteHandle(parent);
                                }
                            }
                            break;

                        case FileMode.Open:
                            directory = fso as Directory;
                            if (directory == null)
                            {
                                Console.WriteLine($"FILE NOT FOUND CreateFile(\"{fileName}\", {access}, {share}, {mode})");
                                return(DokanResult.FileNotFound);
                            }
                            handle = Open(directory, access, share);
                            break;

                        default:
                            throw new System.IO.IOException($"Unsupported FileMode ({mode}) for a directory.");
                        }

                        // Assign the handle
                        info.Context = handle;
                    }
                    else
                    {
                        DirectoryHandle parentHandle = null;
                        File            file;
                        switch (mode)
                        {
                        case FileMode.Append:
                        case FileMode.Truncate:
                        case FileMode.Open:
                            file = fso as File;
                            if (file == null)
                            {
                                Console.WriteLine($"FILE NOT FOUND CreateFile(\"{fileName}\", {access}, {share}, {mode})");
                                return(DokanResult.FileNotFound);
                            }
                            fileHandle = Open(file);
                            break;

                        case FileMode.OpenOrCreate:
                        case FileMode.Create:
                            if (fso == null)
                            {
                                try {
                                    parentHandle = Open(parentDirectory, FileAccess.GenericWrite, FileShare.ReadWrite);
                                    file         = _fileSystem.CreateFile(parentDirectory, name);
                                    fileHandle   = Open(file);
                                } finally {
                                    if (parentHandle != null)
                                    {
                                        parentHandle.Close();
                                        Handles.DeleteHandle(parentHandle);
                                    }
                                }
                            }
                            else
                            {
                                alreadyExists = true;
                            }
                            break;

                        case FileMode.CreateNew:
                            if (fso != null)
                            {
                                Console.WriteLine($"FILE EXISTS CreateFile(\"{fileName}\", {access}, {share}, {mode})");
                                return(DokanResult.FileExists);
                            }
                            try {
                                parentHandle = Open(parentDirectory, FileAccess.GenericWrite, FileShare.ReadWrite);
                                file         = _fileSystem.CreateFile(parentDirectory, name);
                                fileHandle   = Open(file);
                            } finally {
                                if (parentHandle != null)
                                {
                                    parentHandle.Close();
                                    Handles.DeleteHandle(parentHandle);
                                }
                            }
                            break;
                        }

                        // Assign the handle
                        info.Context = fileHandle;
                    }

                    if (fileHandle != null && (mode == FileMode.Create || mode == FileMode.Truncate))
                    {
                        fileHandle.File.SetEndOfFile(0);
                    }

                    if (access == FileAccess.Synchronize)
                    {
                        ((IHandle)info.Context).IsSynchronize = true;
                    }

                    if (info.Context is DirectoryHandle)
                    {
                        info.IsDirectory = true;
                    }
                    else
                    {
                        info.IsDirectory = false;
                    }

                    Console.WriteLine($"**CreateFile(\"{fileName}\", {access}, {share}, {mode}): {(info.Context as IHandle).ID}");
                    (info.Context as IHandle).Messages.Add($"  CreateFile(\"{fileName}\", {access}, {share}, {mode})");


                    if (alreadyExists)
                    {
                        return(DokanResult.AlreadyExists);
                    }
                    else
                    {
                        return(DokanResult.Success);
                    }
                } catch (SharingException) {
                    Console.WriteLine($"SHARING VIOLATION CreateFile(\"{fileName}\", {access}, {share}, {mode})");
                    return(DokanResult.SharingViolation);
                } catch (Exception e) {
                    Console.WriteLine($"ERROR CreateFile(\"{fileName}\", {access}, {share}, {mode})");
                    Console.WriteLine($"{e.Message}");
                    Console.WriteLine(e.StackTrace);
                    return(DokanResult.Error);
                }
            }
        }