Exemplo n.º 1
0
        public static NTStatus Rename(INTFileStore fileStore, string oldName, string newName, SMBFileAttributes searchAttributes, SecurityContext securityContext)
        {
            object        handle;
            FileStatus    fileStatus;
            CreateOptions createOptions = 0;

            // Windows 2000 SP4 clients will use this command to rename directories.
            // Hidden, System and Directory attributes are inclusive.
            if ((searchAttributes & SMBFileAttributes.Directory) == 0)
            {
                createOptions = CreateOptions.FILE_NON_DIRECTORY_FILE;
            }
            ShareAccess shareAccess = ShareAccess.Read | ShareAccess.Write | ShareAccess.Delete;
            NTStatus    status      = fileStore.CreateFile(out handle, out fileStatus, oldName, AccessMask.DELETE, 0, shareAccess, CreateDisposition.FILE_OPEN, createOptions, securityContext);

            if (status != NTStatus.STATUS_SUCCESS)
            {
                return(status);
            }
            FileRenameInformationType2 renameInfo = new FileRenameInformationType2();

            renameInfo.ReplaceIfExists = false;
            renameInfo.FileName        = newName;
            status = fileStore.SetFileInformation(handle, renameInfo);
            fileStore.CloseFile(handle);
            return(status);
        }
Exemplo n.º 2
0
        public NTStatus SetFileInformation(object handle, FileInformation information)
        {
            IO_STATUS_BLOCK ioStatusBlock;

            if (information is FileRenameInformationType2)
            {
                FileRenameInformationType2 fileRenameInformationRemote = (FileRenameInformationType2)information;
                if (ProcessHelper.Is64BitProcess)
                {
                    // We should not modify the FileRenameInformationType2 instance we received - the caller may use it later.
                    FileRenameInformationType2 fileRenameInformationLocal = new FileRenameInformationType2();
                    fileRenameInformationLocal.ReplaceIfExists = fileRenameInformationRemote.ReplaceIfExists;
                    fileRenameInformationLocal.FileName        = ToNativePath(fileRenameInformationRemote.FileName);
                    information = fileRenameInformationLocal;
                }
                else
                {
                    // Note: WOW64 process should use FILE_RENAME_INFORMATION_TYPE_1.
                    // Note: Server 2003 x64 has issues with using FILE_RENAME_INFORMATION under WOW64.
                    FileRenameInformationType1 fileRenameInformationLocal = new FileRenameInformationType1();
                    fileRenameInformationLocal.ReplaceIfExists = fileRenameInformationRemote.ReplaceIfExists;
                    fileRenameInformationLocal.FileName        = ToNativePath(fileRenameInformationRemote.FileName);
                    information = fileRenameInformationLocal;
                }
            }
            else if (information is FileLinkInformationType2)
            {
                FileLinkInformationType2 fileLinkInformationRemote = (FileLinkInformationType2)information;
                if (ProcessHelper.Is64BitProcess)
                {
                    FileRenameInformationType2 fileLinkInformationLocal = new FileRenameInformationType2();
                    fileLinkInformationLocal.ReplaceIfExists = fileLinkInformationRemote.ReplaceIfExists;
                    fileLinkInformationLocal.FileName        = ToNativePath(fileLinkInformationRemote.FileName);
                    information = fileLinkInformationRemote;
                }
                else
                {
                    FileLinkInformationType1 fileLinkInformationLocal = new FileLinkInformationType1();
                    fileLinkInformationLocal.ReplaceIfExists = fileLinkInformationRemote.ReplaceIfExists;
                    fileLinkInformationLocal.FileName        = ToNativePath(fileLinkInformationRemote.FileName);
                    information = fileLinkInformationRemote;
                }
            }
            byte[] buffer = information.GetBytes();
            return(NtSetInformationFile((IntPtr)handle, out ioStatusBlock, buffer, (uint)buffer.Length, (uint)information.FileInformationClass));
        }
Exemplo n.º 3
0
        public void Rename(string path, string newName)
        {
            NTStatus status = fileStore.CreateFile(out object fileHandle, out FileStatus fileStatus, path, AccessMask.GENERIC_ALL, FileAttributes.Normal, ShareAccess.Read, CreateDisposition.FILE_OPEN, 0, null);

            if (status != NTStatus.STATUS_SUCCESS)
            {
                throw new IOException($"Failed to rename file: {status}");
            }
            FileRenameInformationType2 fileRenameInformation = new FileRenameInformationType2();
            string parentPath = Path.GetDirectoryName(path) ?? string.Empty;

            fileRenameInformation.FileName        = Path.Combine(parentPath, newName);
            fileRenameInformation.ReplaceIfExists = false;
            status = fileStore.SetFileInformation(fileHandle, fileRenameInformation);
            fileStore.CloseFile(fileHandle);
            if (status != NTStatus.STATUS_SUCCESS)
            {
                throw new IOException($"Failed to rename file: {status}");
            }
        }
Exemplo n.º 4
0
        protected override Node ExecMove(Node fromNode, Node toNode)
        {
            var fromPath = this.FormatPath(fromNode.PathSet.ElementsPath);

            // In SMB2, FileRenameInformationType2.FileName is the absolute path
            // on the shared folder.
            var toPath = this.FormatPath(toNode.PathSet.ElementsPath);

            using (var hdr = this.GetHandler(fromPath, HandleType.Move, fromNode.Type))
            {
                if (!hdr.Succeeded)
                {
                    this.AddError("ExecMove", $"Create Handle Failed: {fromNode.PathSet.FullPath}");

                    return(null);
                }

                // SMB2
                var info = new FileRenameInformationType2
                {
                    FileName = toPath
                };
                var status = this.Store.SetFileInformation(hdr.Handle, info);

                if (status != NTStatus.STATUS_SUCCESS)
                {
                    if (status == NTStatus.STATUS_SHARING_VIOLATION)
                    {
                        this.AddError("ExecMove", $"Someone holds file / folder: {toNode.PathSet.FullPath}");
                    }
                    else
                    {
                        this.AddError("ExecMove", $"Move Failed: {status}, {toNode.PathSet.FullPath}");
                    }

                    return(null);
                }
            }

            return(toNode);
        }
Exemplo n.º 5
0
        public NTStatus SetFileInformation(object handle, FileInformation information)
        {
            FileHandle fileHandle = (FileHandle)handle;

            if (information is FileBasicInformation)
            {
                FileBasicInformation basicInformation = (FileBasicInformation)information;
                bool isHidden   = ((basicInformation.FileAttributes & FileAttributes.Hidden) > 0);
                bool isReadonly = (basicInformation.FileAttributes & FileAttributes.ReadOnly) > 0;
                bool isArchived = (basicInformation.FileAttributes & FileAttributes.Archive) > 0;
                try
                {
                    m_fileSystem.SetAttributes(fileHandle.Path, isHidden, isReadonly, isArchived);
                }
                catch (Exception ex)
                {
                    if (ex is IOException || ex is UnauthorizedAccessException)
                    {
                        NTStatus status = ToNTStatus(ex);
                        Log(Severity.Verbose, "SetFileInformation: Failed to set file attributes on '{0}'. {1}.", fileHandle.Path, status);
                        return(status);
                    }
                    else
                    {
                        throw;
                    }
                }

                try
                {
                    m_fileSystem.SetDates(fileHandle.Path, basicInformation.CreationTime, basicInformation.LastWriteTime, basicInformation.LastAccessTime);
                }
                catch (Exception ex)
                {
                    if (ex is IOException || ex is UnauthorizedAccessException)
                    {
                        NTStatus status = ToNTStatus(ex);
                        Log(Severity.Verbose, "SetFileInformation: Failed to set file dates on '{0}'. {1}.", fileHandle.Path, status);
                        return(status);
                    }
                    else
                    {
                        throw;
                    }
                }
                return(NTStatus.STATUS_SUCCESS);
            }
            else if (information is FileRenameInformationType2)
            {
                FileRenameInformationType2 renameInformation = (FileRenameInformationType2)information;
                string newFileName = renameInformation.FileName;
                if (!newFileName.StartsWith(@"\"))
                {
                    newFileName = @"\" + newFileName;
                }

                if (fileHandle.Stream != null)
                {
                    fileHandle.Stream.Close();
                }

                // Note: it's possible that we just want to upcase / downcase a filename letter.
                try
                {
                    if (renameInformation.ReplaceIfExists && (IsFileExists(newFileName)))
                    {
                        m_fileSystem.Delete(newFileName);
                    }
                    m_fileSystem.Move(fileHandle.Path, newFileName);
                    Log(Severity.Information, "SetFileInformation: Renamed '{0}' to '{1}'", fileHandle.Path, newFileName);
                }
                catch (Exception ex)
                {
                    if (ex is IOException || ex is UnauthorizedAccessException)
                    {
                        NTStatus status = ToNTStatus(ex);
                        Log(Severity.Verbose, "SetFileInformation: Cannot rename '{0}' to '{1}'. {2}.", fileHandle.Path, newFileName, status);
                        return(status);
                    }
                    else
                    {
                        throw;
                    }
                }
                fileHandle.Path = newFileName;
                return(NTStatus.STATUS_SUCCESS);
            }
            else if (information is FileDispositionInformation)
            {
                if (((FileDispositionInformation)information).DeletePending)
                {
                    // We're supposed to delete the file on close, but it's too late to report errors at this late stage
                    if (fileHandle.Stream != null)
                    {
                        fileHandle.Stream.Close();
                    }

                    try
                    {
                        m_fileSystem.Delete(fileHandle.Path);
                        Log(Severity.Information, "SetFileInformation: Deleted '{0}'", fileHandle.Path);
                    }
                    catch (Exception ex)
                    {
                        if (ex is IOException || ex is UnauthorizedAccessException)
                        {
                            NTStatus status = ToNTStatus(ex);
                            Log(Severity.Information, "SetFileInformation: Error deleting '{0}'. {1}.", fileHandle.Path, status);
                            return(status);
                        }
                        else
                        {
                            throw;
                        }
                    }
                }
                return(NTStatus.STATUS_SUCCESS);
            }
            else if (information is FileAllocationInformation)
            {
                long allocationSize = ((FileAllocationInformation)information).AllocationSize;
                try
                {
                    fileHandle.Stream.SetLength(allocationSize);
                }
                catch (Exception ex)
                {
                    if (ex is IOException || ex is UnauthorizedAccessException)
                    {
                        NTStatus status = ToNTStatus(ex);
                        Log(Severity.Verbose, "SetFileInformation: Cannot set allocation for '{0}'. {1}.", fileHandle.Path, status);
                        return(status);
                    }
                    else
                    {
                        throw;
                    }
                }
                return(NTStatus.STATUS_SUCCESS);
            }
            else if (information is FileEndOfFileInformation)
            {
                long endOfFile = ((FileEndOfFileInformation)information).EndOfFile;
                try
                {
                    fileHandle.Stream.SetLength(endOfFile);
                }
                catch (Exception ex)
                {
                    if (ex is IOException || ex is UnauthorizedAccessException)
                    {
                        NTStatus status = ToNTStatus(ex);
                        Log(Severity.Verbose, "SetFileInformation: Cannot set end of file for '{0}'. {1}.", fileHandle.Path, status);
                        return(status);
                    }
                    else
                    {
                        throw;
                    }
                }
                return(NTStatus.STATUS_SUCCESS);
            }
            else
            {
                return(NTStatus.STATUS_NOT_IMPLEMENTED);
            }
        }