def set_basic_info( self, file_context, file_attributes, creation_time, last_access_time, last_write_time, change_time, file_info, ) -> dict: if self.read_only: raise NTStatusMediaWriteProtected() file_obj = file_context.file_obj if file_attributes != FILE_ATTRIBUTE.INVALID_FILE_ATTRIBUTES: file_obj.attributes = file_attributes if creation_time: file_obj.creation_time = creation_time if last_access_time: file_obj.last_access_time = last_access_time if last_write_time: file_obj.last_write_time = last_write_time if change_time: file_obj.change_time = change_time return file_obj.get_file_info()
def rename(self, file_context, file_name, new_file_name, replace_if_exists): if self.read_only: raise NTStatusMediaWriteProtected() file_name = PureWindowsPath(file_name) new_file_name = PureWindowsPath(new_file_name) # Retrieve file try: file_obj = self._entries[file_name] except KeyError: raise NTStatusObjectNameNotFound() if new_file_name in self._entries: # Case-sensitive comparison if new_file_name.name != self._entries[new_file_name].path.name: pass elif not replace_if_exists: raise NTStatusObjectNameCollision() elif not isinstance(file_obj, FileObj): raise NTStatusAccessDenied() for entry_path in list(self._entries): try: relative = entry_path.relative_to(file_name) new_entry_path = new_file_name / relative entry = self._entries.pop(entry_path) entry.path = new_entry_path self._entries[new_entry_path] = entry except ValueError: continue
def set_file_size(self, file_context, new_size, set_allocation_size): if self.read_only: raise NTStatusMediaWriteProtected() if set_allocation_size: file_context.file_obj.set_allocation_size(new_size) else: file_context.file_obj.set_file_size(new_size)
def set_security(self, file_context, security_information, modification_descriptor): if self.read_only: raise NTStatusMediaWriteProtected() new_descriptor = file_context.file_obj.security_descriptor.evolve( security_information, modification_descriptor) file_context.file_obj.security_descriptor = new_descriptor
def write(self, file_context, buffer, offset, write_to_end_of_file, constrained_io): if self.read_only: raise NTStatusMediaWriteProtected() if constrained_io: return file_context.file_obj.constrained_write(buffer, offset) else: return file_context.file_obj.write(buffer, offset, write_to_end_of_file)
def cleanup(self, file_context, file_name, flags) -> None: if self.read_only: raise NTStatusMediaWriteProtected() # TODO: expose FspCleanupDelete & friends FspCleanupDelete = 0x01 FspCleanupSetAllocationSize = 0x02 FspCleanupSetArchiveBit = 0x10 FspCleanupSetLastAccessTime = 0x20 FspCleanupSetLastWriteTime = 0x40 FspCleanupSetChangeTime = 0x80 file_obj = file_context.file_obj # Delete if flags & FspCleanupDelete: # Check for non-empty direcory if any(key.parent == file_obj.path for key in self._entries): return # Delete immediately try: del self._entries[file_obj.path] except KeyError: raise NTStatusObjectNameNotFound() # Resize if flags & FspCleanupSetAllocationSize: file_obj.adapt_allocation_size(file_obj.file_size) # Set archive bit if flags & FspCleanupSetArchiveBit and isinstance(file_obj, FileObj): file_obj.attributes |= FILE_ATTRIBUTE.FILE_ATTRIBUTE_ARCHIVE # Set last access time if flags & FspCleanupSetLastAccessTime: file_obj.last_access_time = filetime_now() # Set last access time if flags & FspCleanupSetLastWriteTime: file_obj.last_write_time = filetime_now() # Set last access time if flags & FspCleanupSetChangeTime: file_obj.change_time = filetime_now()
def create( self, file_name, create_options, granted_access, file_attributes, security_descriptor, allocation_size, ): if self.read_only: raise NTStatusMediaWriteProtected() file_name = PureWindowsPath(file_name) # `granted_access` is already handle by winfsp # `allocation_size` useless for us # Retrieve file try: parent_file_obj = self._entries[file_name.parent] if isinstance(parent_file_obj, FileObj): raise NTStatusNotADirectory() except KeyError: raise NTStatusObjectNameNotFound() # File/Folder already exists if file_name in self._entries: raise NTStatusObjectNameCollision() if create_options & CREATE_FILE_CREATE_OPTIONS.FILE_DIRECTORY_FILE: file_obj = self._entries[file_name] = FolderObj( file_name, file_attributes, security_descriptor) else: file_obj = self._entries[file_name] = FileObj( file_name, file_attributes, security_descriptor, allocation_size, ) return OpenedObj(file_obj)
def overwrite(self, file_context, file_attributes, replace_file_attributes: bool, allocation_size: int) -> None: if self.read_only: raise NTStatusMediaWriteProtected() file_obj = file_context.file_obj # File attributes file_attributes |= FILE_ATTRIBUTE.FILE_ATTRIBUTE_ARCHIVE if replace_file_attributes: file_obj.attributes = file_attributes else: file_obj.attributes |= file_attributes # Allocation size file_obj.set_allocation_size(allocation_size) # Set times now = filetime_now() file_obj.last_access_time = now file_obj.last_write_time = now file_obj.change_time = now