Ejemplo n.º 1
0
def translate_error(event_bus, operation, path):
    try:
        yield

    except NTStatusError:
        raise

    except FSLocalOperationError as exc:
        raise NTStatusError(exc.ntstatus) from exc

    except FSRemoteOperationError as exc:
        event_bus.send("mountpoint.remote_error",
                       exc=exc,
                       operation=operation,
                       path=path)
        raise NTStatusError(exc.ntstatus) from exc

    except (Cancelled, RunFinishedError) as exc:
        # WinFSP teardown operation doesn't make sure no concurrent operation
        # are running
        raise NTStatusError(NTSTATUS.STATUS_NO_SUCH_DEVICE) from exc

    except Exception as exc:
        logger.exception("Unhandled exception in winfsp mountpoint",
                         operation=operation,
                         path=path)
        event_bus.send("mountpoint.unhandled_error",
                       exc=exc,
                       operation=operation,
                       path=path)
        raise NTStatusError(NTSTATUS.STATUS_INTERNAL_ERROR) from exc
Ejemplo n.º 2
0
 def can_delete(self, file_context, file_name: str) -> None:
     self.fs_access.check_write_rights(file_context.path)
     stat = self.fs_access.entry_info(file_context.path)
     if stat["type"] == "file":
         return
     if file_context.is_root():
         # Cannot remove root mountpoint !
         raise NTStatusError(NTSTATUS.STATUS_RESOURCEMANAGER_READ_ONLY)
     if stat["children"]:
         raise NTStatusError(NTSTATUS.STATUS_DIRECTORY_NOT_EMPTY)
Ejemplo n.º 3
0
    def read_directory(self, file_context, marker):
        entries = []
        stat = self.fs_access.entry_info(file_context.path)

        if stat["type"] == "file":
            raise NTStatusError(NTSTATUS.STATUS_NOT_A_DIRECTORY)

        # NOTE: The "." and ".." directories should ONLY be included
        # if the queried directory is not root

        # Current directory
        if marker is None and not file_context.path.is_root():
            entry = {"file_name": ".", **stat_to_winfsp_attributes(stat)}
            entries.append(entry)
        elif marker == ".":
            marker = None

        # Parent directory
        if marker is None and not file_context.path.is_root():
            parent_stat = self.fs_access.entry_info(file_context.path.parent)
            entry = {
                "file_name": "..",
                **stat_to_winfsp_attributes(parent_stat)
            }
            entries.append(entry)
        elif marker == "..":
            marker = None

        # NOTE: we *do not* rely on alphabetically sorting to compare the
        # marker given `..` is always the first element event if we could
        # have children name before it (`.-foo` for instance)
        iter_children_names = iter(stat["children"])
        if marker is not None:
            for child_name in iter_children_names:
                if child_name == marker:
                    break

        # All remaining children are located after the marker
        for child_name in iter_children_names:
            name = winify_entry_name(child_name)
            child_stat = self.fs_access.entry_info(file_context.path /
                                                   child_name)
            entry = {
                "file_name": name,
                **stat_to_winfsp_attributes(child_stat)
            }
            entries.append(entry)

        return entries
Ejemplo n.º 4
0
def get_path_and_translate_error(
    fs_access: ThreadFSAccess,
    operation: str,
    file_context: Union[OpenedFile, OpenedFolder, str],
    mountpoint: PurePath,
    workspace_id: EntryID,
    timestamp: Optional[DateTime],
) -> Iterator[FsPath]:
    path: FsPath = FsPath("/<unkonwn>")
    try:
        if isinstance(file_context, (OpenedFile, OpenedFolder)):
            path = file_context.path
        else:
            # FsPath conversion might raise an FSNameTooLongError so make
            # sure it runs within the try-except so it can be caught by the
            # FSLocalOperationError filter.
            path = _winpath_to_parsec(file_context)
        yield path

    except NTStatusError:
        raise

    except FSLocalOperationError as exc:
        raise NTStatusError(exc.ntstatus) from exc

    except FSRemoteOperationError as exc:
        fs_access.send_event(
            CoreEvent.MOUNTPOINT_REMOTE_ERROR,
            exc=exc,
            operation=operation,
            path=path,
            mountpoint=mountpoint,
            workspace_id=workspace_id,
            timestamp=timestamp,
        )
        raise NTStatusError(exc.ntstatus) from exc

    except (Cancelled, RunFinishedError) as exc:
        # WinFSP teardown operation doesn't make sure no concurrent operation
        # are running
        raise NTStatusError(NTSTATUS.STATUS_NO_SUCH_DEVICE) from exc

    except TrioDealockTimeoutError as exc:
        # See the similar clause in `fuse_operations` for a detailed explanation
        logger.error(
            "The trio thread is unreachable, a deadlock might have occured",
            operation=operation,
            path=str(path),
            mountpoint=str(mountpoint),
            workspace_id=workspace_id,
            timestamp=timestamp,
        )
        fs_access.send_event(
            CoreEvent.MOUNTPOINT_TRIO_DEADLOCK_ERROR,
            exc=exc,
            operation=operation,
            path=path,
            mountpoint=mountpoint,
            workspace_id=workspace_id,
            timestamp=timestamp,
        )
        raise NTStatusError(NTSTATUS.STATUS_INTERNAL_ERROR) from exc

    except Exception as exc:
        logger.exception(
            "Unhandled exception in winfsp mountpoint",
            operation=operation,
            path=str(path),
            mountpoint=str(mountpoint),
            workspace_id=workspace_id,
            timestamp=timestamp,
        )
        fs_access.send_event(
            CoreEvent.MOUNTPOINT_UNHANDLED_ERROR,
            exc=exc,
            operation=operation,
            path=path,
            mountpoint=mountpoint,
            workspace_id=workspace_id,
            timestamp=timestamp,
        )
        raise NTStatusError(NTSTATUS.STATUS_INTERNAL_ERROR) from exc