/trunk/uspace/srv/fs/fat/fat.h |
---|
115,32 → 115,6 |
}; |
} __attribute__ ((packed)) fat_bs_t; |
#define FAT_ATTR_RDONLY (1 << 0) |
#define FAT_ATTR_VOLLABEL (1 << 3) |
#define FAT_ATTR_SUBDIR (1 << 4) |
typedef struct { |
uint8_t name[8]; |
uint8_t ext[3]; |
uint8_t attr; |
uint8_t reserved; |
uint8_t ctime_fine; |
uint16_t ctime; |
uint16_t cdate; |
uint16_t adate; |
union { |
uint16_t eaidx; /* FAT12/FAT16 */ |
uint16_t firstc_hi; /* FAT32 */ |
}; |
uint16_t mtime; |
uint16_t mdate; |
union { |
uint16_t firstc; /* FAT12/FAT16 */ |
uint16_t firstc_lo; /* FAT32 */ |
}; |
uint32_t size; |
} __attribute__ ((packed)) fat_dentry_t; |
typedef uint16_t fat_cluster_t; |
typedef enum { |
/trunk/uspace/srv/fs/fat/fat_dentry.c |
---|
35,7 → 35,66 |
* @brief Functions that work with FAT directory entries. |
*/ |
#include "fat_dentry.h" |
#define FAT_PAD ' ' |
#define FAT_DENTRY_UNUSED 0x00 |
#define FAT_DENTRY_E5_ESC 0x05 |
#define FAT_DENTRY_DOT 0x2e |
#define FAT_DENTRY_ERASED 0xe5 |
void dentry_name_canonify(fat_dentry_t *d, char *buf) |
{ |
int i; |
for (i = 0; i < FAT_NAME_LEN; i++) { |
if (d->name[i] == FAT_PAD) |
break; |
if (d->name[i] == FAT_DENTRY_E5_ESC) |
*buf++ = 0xe5; |
else |
*buf++ = d->name[i]; |
} |
if (d->ext[0] != FAT_PAD) |
*buf++ = '.'; |
for (i = 0; i < FAT_EXT_LEN; i++) { |
if (d->ext[i] == FAT_PAD) { |
*buf = '\0'; |
return; |
} |
if (d->ext[i] == FAT_DENTRY_E5_ESC) |
*buf++ = 0xe5; |
else |
*buf++ = d->ext[i]; |
} |
*buf = '\0'; |
} |
fat_dentry_clsf_t fat_classify_dentry(fat_dentry_t *d) |
{ |
if (d->attr & FAT_ATTR_VOLLABEL) { |
/* volume label entry */ |
return FAT_DENTRY_SKIP; |
} |
if (d->name[0] == FAT_DENTRY_ERASED) { |
/* not-currently-used entry */ |
return FAT_DENTRY_SKIP; |
} |
if (d->name[0] == FAT_DENTRY_UNUSED) { |
/* never used entry */ |
return FAT_DENTRY_LAST; |
} |
if (d->name[0] == FAT_DENTRY_DOT) { |
/* |
* Most likely '.' or '..'. |
* It cannot occur in a regular file name. |
*/ |
return FAT_DENTRY_SKIP; |
} |
return FAT_DENTRY_VALID; |
} |
/** |
* @} |
*/ |
/trunk/uspace/srv/fs/fat/fat_dentry.h |
---|
33,6 → 33,46 |
#ifndef FAT_FAT_DENTRY_H_ |
#define FAT_FAT_DENTRY_H_ |
#include <stdint.h> |
#define FAT_NAME_LEN 8 |
#define FAT_EXT_LEN 3 |
#define FAT_ATTR_RDONLY (1 << 0) |
#define FAT_ATTR_VOLLABEL (1 << 3) |
#define FAT_ATTR_SUBDIR (1 << 4) |
typedef enum { |
FAT_DENTRY_SKIP, |
FAT_DENTRY_LAST, |
FAT_DENTRY_VALID |
} fat_dentry_clsf_t; |
typedef struct { |
uint8_t name[8]; |
uint8_t ext[3]; |
uint8_t attr; |
uint8_t reserved; |
uint8_t ctime_fine; |
uint16_t ctime; |
uint16_t cdate; |
uint16_t adate; |
union { |
uint16_t eaidx; /* FAT12/FAT16 */ |
uint16_t firstc_hi; /* FAT32 */ |
}; |
uint16_t mtime; |
uint16_t mdate; |
union { |
uint16_t firstc; /* FAT12/FAT16 */ |
uint16_t firstc_lo; /* FAT32 */ |
}; |
uint32_t size; |
} __attribute__ ((packed)) fat_dentry_t; |
extern void dentry_name_canonify(fat_dentry_t *, char *); |
extern fat_dentry_clsf_t fat_classify_dentry(fat_dentry_t *); |
#endif |
/** |
/trunk/uspace/srv/fs/fat/fat_ops.c |
---|
36,6 → 36,8 |
*/ |
#include "fat.h" |
#include "fat_dentry.h" |
#include "fat_fat.h" |
#include "../../vfs/vfs.h" |
#include <libfs.h> |
#include <ipc/ipc.h> |
61,45 → 63,8 |
/** List of cached free FAT nodes. */ |
static LIST_INITIALIZE(ffn_head); |
#define FAT_NAME_LEN 8 |
#define FAT_EXT_LEN 3 |
#define FAT_PAD ' ' |
#define FAT_DENTRY_UNUSED 0x00 |
#define FAT_DENTRY_E5_ESC 0x05 |
#define FAT_DENTRY_DOT 0x2e |
#define FAT_DENTRY_ERASED 0xe5 |
#define min(a, b) ((a) < (b) ? (a) : (b)) |
static void dentry_name_canonify(fat_dentry_t *d, char *buf) |
{ |
int i; |
for (i = 0; i < FAT_NAME_LEN; i++) { |
if (d->name[i] == FAT_PAD) |
break; |
if (d->name[i] == FAT_DENTRY_E5_ESC) |
*buf++ = 0xe5; |
else |
*buf++ = d->name[i]; |
} |
if (d->ext[0] != FAT_PAD) |
*buf++ = '.'; |
for (i = 0; i < FAT_EXT_LEN; i++) { |
if (d->ext[i] == FAT_PAD) { |
*buf = '\0'; |
return; |
} |
if (d->ext[i] == FAT_DENTRY_E5_ESC) |
*buf++ = 0xe5; |
else |
*buf++ = d->ext[i]; |
} |
*buf = '\0'; |
} |
static int dev_phone = -1; /* FIXME */ |
static void *dev_buffer = NULL; /* FIXME */ |
299,36 → 264,6 |
return bps; |
} |
typedef enum { |
FAT_DENTRY_SKIP, |
FAT_DENTRY_LAST, |
FAT_DENTRY_VALID |
} fat_dentry_clsf_t; |
static fat_dentry_clsf_t fat_classify_dentry(fat_dentry_t *d) |
{ |
if (d->attr & FAT_ATTR_VOLLABEL) { |
/* volume label entry */ |
return FAT_DENTRY_SKIP; |
} |
if (d->name[0] == FAT_DENTRY_ERASED) { |
/* not-currently-used entry */ |
return FAT_DENTRY_SKIP; |
} |
if (d->name[0] == FAT_DENTRY_UNUSED) { |
/* never used entry */ |
return FAT_DENTRY_LAST; |
} |
if (d->name[0] == FAT_DENTRY_DOT) { |
/* |
* Most likely '.' or '..'. |
* It cannot occur in a regular file name. |
*/ |
return FAT_DENTRY_SKIP; |
} |
return FAT_DENTRY_VALID; |
} |
static void fat_node_sync(fat_node_t *node) |
{ |
/* TODO */ |