| 1 | |
|---|
| 2 | |
|---|
| 3 | |
|---|
| 4 | |
|---|
| 5 | |
|---|
| 6 | |
|---|
| 7 | |
|---|
| 8 | |
|---|
| 9 | |
|---|
| 10 | |
|---|
| 11 | |
|---|
| 12 | |
|---|
| 13 | |
|---|
| 14 | |
|---|
| 15 | |
|---|
| 16 | |
|---|
| 17 | |
|---|
| 18 | |
|---|
| 19 | |
|---|
| 20 | |
|---|
| 21 | #include "muscle-filesystem.h" |
|---|
| 22 | #include <opensc/errors.h> |
|---|
| 23 | #include <memory.h> |
|---|
| 24 | #include <stdio.h> |
|---|
| 25 | #include <assert.h> |
|---|
| 26 | |
|---|
| 27 | #define MSCFS_NO_MEMORY SC_ERROR_OUT_OF_MEMORY |
|---|
| 28 | #define MSCFS_INVALID_ARGS SC_ERROR_INVALID_ARGUMENTS |
|---|
| 29 | #define MSCFS_FILE_NOT_FOUND SC_ERROR_FILE_NOT_FOUND |
|---|
| 30 | #define MSCFS_CACHE_INCREMENT 128 |
|---|
| 31 | |
|---|
| 32 | static msc_id rootId = { { 0x3F, 0x00, 0x3F, 0x00 } }; |
|---|
| 33 | |
|---|
| 34 | static const u8* ignoredFiles[] = { |
|---|
| 35 | (const u8*)"l0\0\0", |
|---|
| 36 | (const u8*)"L0\0\0", |
|---|
| 37 | NULL |
|---|
| 38 | }; |
|---|
| 39 | |
|---|
| 40 | mscfs_t *mscfs_new(void) { |
|---|
| 41 | mscfs_t *fs = (mscfs_t*)malloc(sizeof(mscfs_t)); |
|---|
| 42 | memset(fs, 0, sizeof(mscfs_t)); |
|---|
| 43 | memcpy(fs->currentPath, "\x3F\x00", 2); |
|---|
| 44 | return fs; |
|---|
| 45 | } |
|---|
| 46 | |
|---|
| 47 | void mscfs_free(mscfs_t *fs) { |
|---|
| 48 | mscfs_clear_cache(fs); |
|---|
| 49 | } |
|---|
| 50 | |
|---|
| 51 | void mscfs_clear_cache(mscfs_t* fs) { |
|---|
| 52 | if(!fs->cache.array) { |
|---|
| 53 | return; |
|---|
| 54 | } |
|---|
| 55 | free(fs->cache.array); |
|---|
| 56 | fs->cache.array = NULL; |
|---|
| 57 | fs->cache.totalSize = 0; |
|---|
| 58 | fs->cache.size = 0; |
|---|
| 59 | } |
|---|
| 60 | |
|---|
| 61 | static int mscfs_is_ignored(mscfs_t* fs, msc_id objectId) |
|---|
| 62 | { |
|---|
| 63 | int ignored = 0; |
|---|
| 64 | const u8** ptr = ignoredFiles; |
|---|
| 65 | while(ptr && *ptr && !ignored) { |
|---|
| 66 | if(0 == memcmp(objectId.id, *ptr, 4)) |
|---|
| 67 | ignored = 1; |
|---|
| 68 | ptr++; |
|---|
| 69 | } |
|---|
| 70 | return ignored; |
|---|
| 71 | } |
|---|
| 72 | |
|---|
| 73 | int mscfs_push_file(mscfs_t* fs, mscfs_file_t *file) |
|---|
| 74 | { |
|---|
| 75 | mscfs_cache_t *cache = &fs->cache; |
|---|
| 76 | if(!cache->array || cache->size == cache->totalSize) { |
|---|
| 77 | int length = cache->totalSize + MSCFS_CACHE_INCREMENT; |
|---|
| 78 | mscfs_file_t *oldArray; |
|---|
| 79 | cache->totalSize = length; |
|---|
| 80 | oldArray = cache->array; |
|---|
| 81 | cache->array = malloc(sizeof(mscfs_file_t) * length); |
|---|
| 82 | if(!cache->array) |
|---|
| 83 | return MSCFS_NO_MEMORY; |
|---|
| 84 | if(oldArray) { |
|---|
| 85 | memcpy(cache->array, oldArray, sizeof(mscfs_file_t) * cache->size); |
|---|
| 86 | free(oldArray); |
|---|
| 87 | } |
|---|
| 88 | } |
|---|
| 89 | cache->array[cache->size] = *file; |
|---|
| 90 | cache->size++; |
|---|
| 91 | return 0; |
|---|
| 92 | } |
|---|
| 93 | |
|---|
| 94 | int mscfs_update_cache(mscfs_t* fs) { |
|---|
| 95 | mscfs_file_t file; |
|---|
| 96 | int r; |
|---|
| 97 | mscfs_clear_cache(fs); |
|---|
| 98 | r = fs->listFile(&file, 1, fs->udata); |
|---|
| 99 | if(r == 0) |
|---|
| 100 | return 0; |
|---|
| 101 | else if(r < 0) |
|---|
| 102 | return r; |
|---|
| 103 | while(1) { |
|---|
| 104 | if(!mscfs_is_ignored(fs, file.objectId)) { |
|---|
| 105 | |
|---|
| 106 | u8* oid = file.objectId.id; |
|---|
| 107 | if(oid[2] == 0 && oid[3] == 0) { |
|---|
| 108 | oid[2] = oid[0]; |
|---|
| 109 | oid[3] = oid[1]; |
|---|
| 110 | oid[0] = 0x3F; |
|---|
| 111 | oid[1] = 0x00; |
|---|
| 112 | file.ef = 0; |
|---|
| 113 | } else { |
|---|
| 114 | file.ef = 1; |
|---|
| 115 | } |
|---|
| 116 | |
|---|
| 117 | mscfs_push_file(fs, &file); |
|---|
| 118 | } |
|---|
| 119 | r = fs->listFile(&file, 0, fs->udata); |
|---|
| 120 | if(r == 0) |
|---|
| 121 | break; |
|---|
| 122 | else if(r < 0) |
|---|
| 123 | return r; |
|---|
| 124 | } |
|---|
| 125 | return fs->cache.size; |
|---|
| 126 | } |
|---|
| 127 | |
|---|
| 128 | void mscfs_check_cache(mscfs_t* fs) |
|---|
| 129 | { |
|---|
| 130 | if(!fs->cache.array) { |
|---|
| 131 | mscfs_update_cache(fs); |
|---|
| 132 | } |
|---|
| 133 | } |
|---|
| 134 | |
|---|
| 135 | int mscfs_lookup_path(mscfs_t* fs, const u8 *path, int pathlen, msc_id* objectId, int isDirectory) |
|---|
| 136 | { |
|---|
| 137 | u8* oid = objectId->id; |
|---|
| 138 | if ((pathlen & 1) != 0) |
|---|
| 139 | return MSCFS_INVALID_ARGS; |
|---|
| 140 | if(isDirectory) { |
|---|
| 141 | |
|---|
| 142 | if((0 == memcmp(path, "\x3F\x00", 2) && pathlen == 4) |
|---|
| 143 | || (0 == memcmp(fs->currentPath, "\x3F\x00", 2) && pathlen == 2)) { |
|---|
| 144 | oid[0] = path[pathlen - 2]; |
|---|
| 145 | oid[1] = path[pathlen - 1]; |
|---|
| 146 | oid[2] = oid[3] = 0; |
|---|
| 147 | } else { |
|---|
| 148 | return MSCFS_INVALID_ARGS; |
|---|
| 149 | } |
|---|
| 150 | } |
|---|
| 151 | oid[0] = fs->currentPath[0]; |
|---|
| 152 | oid[1] = fs->currentPath[1]; |
|---|
| 153 | |
|---|
| 154 | if(pathlen > 2 && memcmp(path, "\x3F\x00", 2) == 0) { |
|---|
| 155 | path += 2; |
|---|
| 156 | pathlen -= 2; |
|---|
| 157 | oid[0] = 0x3F; |
|---|
| 158 | oid[1] = 0x00; |
|---|
| 159 | } |
|---|
| 160 | |
|---|
| 161 | if(pathlen > 4) |
|---|
| 162 | return MSCFS_INVALID_ARGS; |
|---|
| 163 | |
|---|
| 164 | if(0 == memcmp(path, "\x3F\x00", 2) && pathlen == 2) { |
|---|
| 165 | oid[0] = oid[2] = path[0]; |
|---|
| 166 | oid[1] = oid[3] = path[1]; |
|---|
| 167 | } else if(pathlen == 2) { |
|---|
| 168 | oid[2] = path[0]; |
|---|
| 169 | oid[3] = path[1]; |
|---|
| 170 | } else if(pathlen == 4) { |
|---|
| 171 | oid[0] = path[0]; |
|---|
| 172 | oid[1] = path[1]; |
|---|
| 173 | oid[2] = path[2]; |
|---|
| 174 | oid[3] = path[3]; |
|---|
| 175 | } |
|---|
| 176 | |
|---|
| 177 | return 0; |
|---|
| 178 | } |
|---|
| 179 | |
|---|
| 180 | int mscfs_lookup_local(mscfs_t* fs, const int id, msc_id* objectId) |
|---|
| 181 | { |
|---|
| 182 | u8* oid = objectId->id; |
|---|
| 183 | oid[0] = fs->currentPath[0]; |
|---|
| 184 | oid[1] = fs->currentPath[1]; |
|---|
| 185 | oid[2] = (id >> 8) & 0xFF; |
|---|
| 186 | oid[3] = id & 0xFF; |
|---|
| 187 | return 0; |
|---|
| 188 | } |
|---|
| 189 | |
|---|
| 190 | |
|---|
| 191 | int mscfs_check_selection(mscfs_t *fs, int requiredItem) |
|---|
| 192 | { |
|---|
| 193 | if(fs->currentPath[0] == 0 && fs->currentPath[1] == 0) |
|---|
| 194 | return MSCFS_INVALID_ARGS; |
|---|
| 195 | if(requiredItem == 1 && fs->currentFile[0] == 0 && fs->currentFile[1] == 0) |
|---|
| 196 | return MSCFS_INVALID_ARGS; |
|---|
| 197 | return 0; |
|---|
| 198 | } |
|---|
| 199 | |
|---|
| 200 | int mscfs_loadFileInfo(mscfs_t* fs, const u8 *path, int pathlen, mscfs_file_t **file_data, int* idx) |
|---|
| 201 | { |
|---|
| 202 | msc_id fullPath; |
|---|
| 203 | int x; |
|---|
| 204 | assert(fs != NULL && path != NULL && file_data != NULL); |
|---|
| 205 | mscfs_lookup_path(fs, path, pathlen, &fullPath, 0); |
|---|
| 206 | |
|---|
| 207 | |
|---|
| 208 | mscfs_check_cache(fs); |
|---|
| 209 | if(idx) *idx = -1; |
|---|
| 210 | for(x = 0; x < fs->cache.size; x++) { |
|---|
| 211 | msc_id objectId; |
|---|
| 212 | *file_data = &fs->cache.array[x]; |
|---|
| 213 | objectId = (*file_data)->objectId; |
|---|
| 214 | if(0 == memcmp(objectId.id, fullPath.id, 4)) { |
|---|
| 215 | if(idx) *idx = x; |
|---|
| 216 | break; |
|---|
| 217 | } |
|---|
| 218 | *file_data = NULL; |
|---|
| 219 | } |
|---|
| 220 | if(*file_data == NULL && (0 == memcmp("\x3F\x00\x00\x00", fullPath.id, 4) || 0 == memcmp("\x3F\x00\x3F\x00", fullPath.id, 4 ))) { |
|---|
| 221 | static mscfs_file_t ROOT_FILE; |
|---|
| 222 | ROOT_FILE.ef = 0; |
|---|
| 223 | ROOT_FILE.size = 0; |
|---|
| 224 | |
|---|
| 225 | ROOT_FILE.objectId = rootId; |
|---|
| 226 | |
|---|
| 227 | ROOT_FILE.read = 0; |
|---|
| 228 | ROOT_FILE.write = 0x02; |
|---|
| 229 | ROOT_FILE.delete = 0x02; |
|---|
| 230 | |
|---|
| 231 | *file_data = &ROOT_FILE; |
|---|
| 232 | if(idx) *idx = -2; |
|---|
| 233 | } else if(*file_data == NULL) { |
|---|
| 234 | return MSCFS_FILE_NOT_FOUND; |
|---|
| 235 | } |
|---|
| 236 | |
|---|
| 237 | return 0; |
|---|
| 238 | } |
|---|