fsctl/src/fugue/core/dirent.c

86 lines
1.9 KiB
C

#include "fsctl/fugue/dirent.h"
#include "fsctl/fugue/cluster.h"
#include "fsctl/fugue/bits/fat.h"
//---
// Internals
//---
/* _fugue_dirent_checksum() : Fugue checksum handling */
static uint8_t _fugue_dirent_checksum(uintptr_t directory)
{
uint8_t *block;
uint8_t checksum;
int a;
int b;
checksum = 0;
block = (void *)directory;
for (int i = 0 ; i < 11 ; ++i)
{
checksum = checksum & 0xff;
a = checksum / 2;
b = checksum * 128;
checksum = a | b;
checksum = checksum + block[i];
}
checksum = checksum & 0xff;
return checksum;
}
//---
// Public
//---
/* fugue_dirent_dir_fetch() : fetch the current dir blob and walk to next */
void *fugue_dirent_dir_fetch(fugue_dir_t *dirent)
{
void *dir;
dir = (void*)dirent->current_dir_addr;
if (dir == NULL)
return NULL;
dirent->current_dir_addr += 32;
if (dirent->current_dir_addr < dirent->cluster_addr_end)
return dir;
dirent->cluster_addr_start = fugue_cluster_find_next(
&dirent->_private.fs,
dirent->cluster_idx
);
dirent->cluster_addr_end = dirent->cluster_addr_start;
if (dirent->cluster_addr_start != 0x00000000)
dirent->cluster_addr_end += dirent->_private.fs.props.cluster_size;
return dir;
}
/* fugue_dirent_name_fetch() : fetch fragment */
int fugue_dirent_name_fetch(fugue_dir_t *dirent, fugue_file_t *file, void *dir)
{
struct fugue_fat_dir_name *lfn;
lfn = (void *)dir;
//---
// check directory block validity
//---
if (lfn->DIR_Attr != FUGUE_DIR_ATTR_LFN)
return -1;
if (lfn->DIR_Type != 0x00)
return -2;
if (lfn->DIR_FstClus != 0x0000)
return -3;
//TODO : check Secquence validity
if (lfn->checksum != _fugue_dirent_checksum(dirent->current_dir_addr))
return -5;
//---
// Dump name fragment
//---
//TODO: dump
return -1;
}