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); }
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)); }
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}"); } }
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); }
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); } }