aboutsummaryrefslogtreecommitdiff
path: root/mirai.old/invocations/fs/viewstack.zig
blob: c3c9b6d8e288c8962e3f8f80ae5c6d3e11a70c02 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
//! Viewstack invocation - List contents of a stack

const afs = @import("../../fs/afs/afs.zig");
const ahci = @import("../../drivers/ahci/ahci.zig");
const copy = @import("../../utils/mem/copy.zig");
const fs_limits = @import("../../common/limits/fs.zig");
const handler = @import("../handler.zig");
const int = @import("../../utils/types/int.zig");
const location = @import("../../utils/fs/location.zig");
const memory_limits = @import("../../common/limits/memory.zig");
const ptr = @import("../../utils/types/ptr.zig");
const result = @import("../../utils/types/result.zig");
const sensei = @import("../../kata/sensei/sensei.zig");
const slice = @import("../../utils/mem/slice.zig");

const MAX_ENTRY_IDENTITY: usize = 64;
const MAX_ENTRY_OWNER: usize = 64;

const UserStackEntry = extern struct {
    identity: [MAX_ENTRY_IDENTITY]u8,
    identity_len: u8,
    is_stack: bool,
    owner_name_len: u8,
    permission_type: u8,
    size: u32,
    modified_time: u64,
    owner_name: [MAX_ENTRY_OWNER]u8,
};

var afs_instance: ?*afs.AFS(ahci.BlockDevice) = null;

pub fn set_afs_instance(fs: *afs.AFS(ahci.BlockDevice)) void {
    afs_instance = fs;
}

pub fn invoke(ctx: *handler.InvocationContext) void {
    const fs = afs_instance orelse return result.set_error(ctx);

    const location_ptr = ctx.rdi;
    const location_len = ctx.rsi;
    const entries_ptr = ctx.rdx;
    const max_entries = ctx.r10;

    if (!memory_limits.is_valid_kata_pointer(location_ptr) or !memory_limits.is_valid_kata_pointer(entries_ptr)) {
        return result.set_error(ctx);
    }

    if (location_len > fs_limits.MAX_LOCATION_LENGTH) return result.set_error(ctx);

    var location_buf: [fs_limits.MAX_LOCATION_LENGTH]u8 = undefined;
    copy.from_ptr(&location_buf, location_ptr, location_len);
    const loc = location_buf[0..location_len];

    const kata = sensei.get_current_kata();
    const current_cluster: u64 = if (kata) |k| k.current_cluster else 0;

    const target_cluster = location.resolve_to_cluster(fs, loc, current_cluster) orelse {
        return result.set_error(ctx);
    };

    var items: [fs_limits.MAX_STACK_ITEMS]afs.StackItem = undefined;
    const item_count = fs.list_stack(target_cluster, &items) catch return result.set_error(ctx);

    const user_entries = slice.typed_ptr(UserStackEntry, entries_ptr);
    const copy_count = @min(item_count, max_entries);

    for (0..copy_count) |i| {
        const item = &items[i];
        var user_entry = &user_entries[i];

        const identity = item.get_identity();
        const id_len = @min(identity.len, MAX_ENTRY_IDENTITY - 1);
        copy.bytes(user_entry.identity[0..id_len], identity[0..id_len]);
        user_entry.identity_len = @intCast(id_len);
        user_entry.size = item.size;
        user_entry.is_stack = item.is_stack;
        user_entry.modified_time = item.modified_time;

        const owner = item.get_owner();
        const owner_len = @min(owner.len, MAX_ENTRY_OWNER - 1);
        copy.bytes(user_entry.owner_name[0..owner_len], owner[0..owner_len]);
        user_entry.owner_name_len = @intCast(owner_len);
        user_entry.permission_type = item.permission_type;
    }

    result.set_value(ctx, copy_count);
}