summaryrefslogtreecommitdiff
path: root/libs/revolution/src/nand/NANDCheck.c
blob: 3f7630af1281e559aecabbfc741ac5bd160e36df (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
88
89
90
91
92
93
94
#include <revolution/nand.h>
#include <revolution/fs.h>

static const char* USER_DIR_LIST[] = {
    "/meta",
    "/ticket",
    "/title/00010000",
    "/title/00010001",
    "/title/00010003",
    "/title/00010004",
    "/title/00010005",
    "/title/00010006",
    "/title/00010007",
    "/shared2/title",
    NULL,
};

s32 nandCalcUsage(u32* fsBlock, u32* inode, const char* dir_list[]) {
    ISFSError ret = ISFS_ERROR_UNKNOWN;
    *fsBlock = 0;
    *inode = 0;

    while (*dir_list) {
        u32 blk = 0;
        u32 node = 0;
        ret = ISFS_GetUsage((const u8*)*dir_list, &blk, &node);

        if (ret == ISFS_ERROR_OK) {
            *fsBlock += blk;
            *inode += node;
        } else if (ret == ISFS_ERROR_NOEXISTS) {
            ret = ISFS_ERROR_OK;
        } else {
            break;
        }

        ++dir_list;
    }

    return ret;
}

ISFSError nandCalcUserUsage(u32* fsBlock, u32* inode) {
    return nandCalcUsage(fsBlock, inode, USER_DIR_LIST);
}

static u32 nandCheck(const u32 reqBlock, const u32 reqInode, const u32 homeBlock, const u32 homeInode, const u32 userBlock, const u32 userInode) {
    u32 answer = 0;

    if (homeBlock + reqBlock > 0x400) {
        answer |= 1;
    }
    
    if (homeInode + reqInode > 0x21) {
        answer |= 2;
    }

    if (userBlock + reqBlock > 0x4400) {
        answer |= 4;
    }

    if (userInode + reqInode > 0xFA0) {
        answer |= 8;
    }

    return answer;
}

s32 NANDCheck(const u32 fsBlock, const u32 inode, u32* answer) {
    ISFSError ret = ISFS_ERROR_UNKNOWN;
    u32 homeBlocks = 0xFFFFFFFF;
    u32 homeInodes = 0xFFFFFFFF;
    u32 userBlocks = 0xFFFFFFFF;
    u32 userInodes = 0xFFFFFFFF;

    if (!nandIsInitialized()) {
        return NAND_RESULT_FATAL_ERROR;
    }

    ret = ISFS_GetUsage((const u8*)nandGetHomeDir(), &homeBlocks, &homeInodes);

    if (ret != ISFS_ERROR_OK) {
        return nandConvertErrorCode(ret);
    }

    ret = nandCalcUserUsage(&userBlocks, &userInodes);

    if (ret != ISFS_ERROR_OK) {
        return nandConvertErrorCode(ret);
    }

    *answer = nandCheck(fsBlock, inode, homeBlocks, homeInodes, userBlocks, userInodes);
    return NAND_RESULT_OK;
}