/**
* @file
*
* @ingroup DOSFS
*
* @brief The MSDOS Filesystem Constants/Data Structures/Prototypes
*/
/*
* Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
* Author: Eugeny S. Mints <Eugeny.Mints@oktet.ru>
*
* Modifications to support UTF-8 in the file system are
* Copyright (c) 2013 embedded brains GmbH & Co. KG
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#ifndef __DOSFS_MSDOS_H__
#define __DOSFS_MSDOS_H__
#include <rtems.h>
#include <rtems/libio_.h>
#include <rtems/dosfs.h>
#include <rtems/thread.h>
#include "fat.h"
#include "fat_file.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @addtogroup DOSFS
*
* @{
*/
#define MSDOS_NAME_NOT_FOUND_ERR 0x7D01
/*
* This structure identifies the instance of the filesystem on the MSDOS
* level.
*/
typedef struct msdos_fs_info_s
{
fat_fs_info_t fat; /*
* volume
* description
*/
const rtems_filesystem_file_handlers_r *directory_handlers; /*
* a set of routines
* that handles the
* nodes of directory
* type
*/
const rtems_filesystem_file_handlers_r *file_handlers; /*
* a set of routines
* that handles the
* nodes of file
* type
*/
rtems_recursive_mutex vol_mutex;
uint8_t *cl_buf; /*
* just placeholder
* for anything
*/
rtems_dosfs_convert_control *converter;
} msdos_fs_info_t;
static inline void msdos_fs_lock(msdos_fs_info_t *fs_info)
{
rtems_recursive_mutex_lock(&fs_info->vol_mutex);
}
static inline void msdos_fs_unlock(msdos_fs_info_t *fs_info)
{
rtems_recursive_mutex_unlock(&fs_info->vol_mutex);
}
/* a set of routines that handle the nodes which are directories */
extern const rtems_filesystem_file_handlers_r msdos_dir_handlers;
/* a set of routines that handle the nodes which are files */
extern const rtems_filesystem_file_handlers_r msdos_file_handlers;
/*
* Macros for fetching fields from 32 bytes long FAT Directory Entry
* Structure
*/
#define MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE 32 /* 32 bytes */
#define MSDOS_DIR_NAME(x) (char *)((x) + 0)
#define MSDOS_DIR_ENTRY_TYPE(x) (uint8_t *)((x) + 0)
#define MSDOS_DIR_ATTR(x) (uint8_t *)((x) + 11)
#define MSDOS_DIR_NT_RES(x) (uint8_t *)((x) + 12)
#define MSDOS_DIR_LFN_CHECKSUM(x) (uint8_t *)((x) + 13)
#define MSDOS_DIR_CRT_TIME_TENTH(x) (uint8_t *)((x) + 13)
#define MSDOS_DIR_CRT_TIME(x) (uint16_t *)((x) + 14)
#define MSDOS_DIR_CRT_DATE(x) (uint16_t *)((x) + 16)
#define MSDOS_DIR_LAST_ACCESS_DATE(x) (uint16_t *)((x) + 18)
#define MSDOS_DIR_FIRST_CLUSTER_HI(x) (uint16_t *)((x) + 20)
#define MSDOS_DIR_WRITE_TIME(x) (uint16_t *)((x) + 22)
#define MSDOS_DIR_WRITE_DATE(x) (uint16_t *)((x) + 24)
#define MSDOS_DIR_FIRST_CLUSTER_LOW(x) (uint16_t *)((x) + 26)
#define MSDOS_DIR_FILE_SIZE(x) (uint32_t *)((x) + 28)
#define MSDOS_EXTRACT_CLUSTER_NUM(p) \
(uint32_t)( (CF_LE_W(*MSDOS_DIR_FIRST_CLUSTER_LOW(p))) | \
((uint32_t)(CF_LE_W((*MSDOS_DIR_FIRST_CLUSTER_HI(p))))<<16) )
/*
* Fields offset in 32 bytes long FAT Directory Entry
* Structure
*/
#define MSDOS_FILE_SIZE_OFFSET 28
#define MSDOS_FILE_NAME_OFFSET 0
#define MSDOS_FIRST_CLUSTER_HI_OFFSET 20
#define MSDOS_FIRST_CLUSTER_LOW_OFFSET 26
#define MSDOS_FILE_WDATE_OFFSET 24
#define MSDOS_FILE_WTIME_OFFSET 22
#define MSDOS_FILE_ADATE_OFFSET 18
#define MSDOS_FILE_CDATE_OFFSET 16
#define MSDOS_FILE_CTIME_OFFSET 14
/*
* Possible values of DIR_Attr field of 32 bytes long FAT Directory Entry
* Structure
*/
#define MSDOS_ATTR_READ_ONLY 0x01
#define MSDOS_ATTR_HIDDEN 0x02
#define MSDOS_ATTR_SYSTEM 0x04
#define MSDOS_ATTR_VOLUME_ID 0x08
#define MSDOS_ATTR_DIRECTORY 0x10
#define MSDOS_ATTR_ARCHIVE 0x20
#define MSDOS_ATTR_LFN (MSDOS_ATTR_READ_ONLY | \
MSDOS_ATTR_HIDDEN | \
MSDOS_ATTR_SYSTEM | \
MSDOS_ATTR_VOLUME_ID)
#define MSDOS_ATTR_LFN_MASK (MSDOS_ATTR_READ_ONLY | \
MSDOS_ATTR_HIDDEN | \
MSDOS_ATTR_SYSTEM | \
MSDOS_ATTR_VOLUME_ID | \
MSDOS_ATTR_DIRECTORY | \
MSDOS_ATTR_ARCHIVE)
#define MSDOS_LAST_LONG_ENTRY 0x40
#define MSDOS_LAST_LONG_ENTRY_MASK 0x3F
#define MSDOS_DT_2SECONDS_MASK 0x1F /* seconds divided by 2 */
#define MSDOS_DT_2SECONDS_SHIFT 0
#define MSDOS_DT_MINUTES_MASK 0x7E0 /* minutes */
#define MSDOS_DT_MINUTES_SHIFT 5
#define MSDOS_DT_HOURS_MASK 0xF800 /* hours */
#define MSDOS_DT_HOURS_SHIFT 11
#define MSDOS_DD_DAY_MASK 0x1F /* day of month */
#define MSDOS_DD_DAY_SHIFT 0
#define MSDOS_DD_MONTH_MASK 0x1E0 /* month */
#define MSDOS_DD_MONTH_SHIFT 5
#define MSDOS_DD_YEAR_MASK 0xFE00 /* year - 1980 */
#define MSDOS_DD_YEAR_SHIFT 9
/*
* Possible values of DIR_Name[0] field of 32 bytes long FAT Directory Entry
* Structure
*/
#define MSDOS_THIS_DIR_ENTRY_EMPTY 0xE5
#define MSDOS_THIS_DIR_ENTRY_AND_REST_EMPTY 0x00
/*
* Number of characters per directory entry for a long filename.
*/
#define MSDOS_LFN_LEN_PER_ENTRY (13)
/*
* Macros for names parsing and formatting
*/
#define MSDOS_NAME_MAX_UTF8_BYTES_PER_CHAR 4
#define MSDOS_NAME_MIN_UTF8_BYTES_PER_CHAR 1
#define MSDOS_SHORT_BASE_LEN 8 /* 8 characters */
#define MSDOS_SHORT_EXT_LEN 3 /* 3 characters */
#define MSDOS_SHORT_NAME_LEN (MSDOS_SHORT_BASE_LEN+\
MSDOS_SHORT_EXT_LEN) /* 11 chars */
#define MSDOS_NAME_MAX_LNF_LEN (255)
#define MSDOS_NAME_MAX MSDOS_SHORT_NAME_LEN
#define MSDOS_NAME_MAX_UTF8_SFN_BYTES (MSDOS_NAME_MAX *\
MSDOS_NAME_MAX_UTF8_BYTES_PER_CHAR)
#define MSDOS_NAME_MAX_WITH_DOT (MSDOS_NAME_MAX + 1)
#define MSDOS_SFN_MAX_WITH_DOT_UTF8_BYTES (MSDOS_NAME_MAX_WITH_DOT *\
MSDOS_NAME_MAX_UTF8_BYTES_PER_CHAR)
#define MSDOS_NAME_MAX_LFN_WITH_DOT (260)
#define MSDOS_NAME_LFN_BYTES_PER_CHAR (2)
#define MSDOS_NAME_MAX_LFN_BYTES (MSDOS_NAME_MAX_LFN_WITH_DOT *\
MSDOS_NAME_LFN_BYTES_PER_CHAR)
#define MSDOS_NAME_MAX_UTF8_LFN_BYTES (MSDOS_NAME_MAX_LFN_WITH_DOT *\
MSDOS_NAME_MAX_UTF8_BYTES_PER_CHAR)
#define MSDOS_ENTRY_LFN_UTF8_BYTES (MSDOS_LFN_LEN_PER_ENTRY *\
MSDOS_NAME_MAX_UTF8_BYTES_PER_CHAR)
extern const char *const MSDOS_DOT_NAME; /* ".", padded to MSDOS_NAME chars */
extern const char *const MSDOS_DOTDOT_NAME; /* ".", padded to MSDOS_NAME chars */
typedef enum msdos_name_types_e
{
MSDOS_NAME_INVALID = 0, /* Unknown name type. Has invalid characters. */
MSDOS_NAME_SHORT, /* Name can be short. */
MSDOS_NAME_LONG /* Name is long; cannot be short. */
} msdos_name_type_t;
typedef enum msdos_token_types_e
{
MSDOS_NO_MORE_PATH,
MSDOS_CURRENT_DIR,
MSDOS_UP_DIR,
MSDOS_NAME,
MSDOS_INVALID_TOKEN
} msdos_token_types_t;
/* Others macros */
#define MSDOS_RES_NT_VALUE 0x00
#define MSDOS_INIT_DIR_SIZE 0x00
/* "dot" entry offset in a directory */
#define MSDOS_DOT_DIR_ENTRY_OFFSET 0x00 /* first entry in directory */
/* "dotdot" entry offset in a directory */
#define MSDOS_DOTDOT_DIR_ENTRY_OFFSET 0x20 /* second entry in directory */
/* 'p' should be char* */
#define DOT_NODE_P(p) ((char *)(p))
#define DOTDOT_NODE_P(p) ((char *)((p) + MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE))
/* Size limits for files and directories */
#define MSDOS_MAX_DIR_LENGTH 0x200000 /* 2,097,152 bytes */
#define MSDOS_MAX_FILE_SIZE 0xFFFFFFFF /* 4 Gb */
/*
* The number of 32 bytes long FAT Directory Entry
* Structures per 512 bytes sector
*/
#define MSDOS_DPS512_NUM 16
/**
* @brief Shut down the MSDOS filesystem.
*
* MSDOS shut down handler implementation
*/
void msdos_shut_down(rtems_filesystem_mount_table_entry_t *temp_mt_entry);
void msdos_eval_path(rtems_filesystem_eval_path_context_t *ctx);
/**
* @brief Call the Fat-File close routine.
*
* Free node handler implementation for the filesystem operations table.
*/
void msdos_free_node_info(const rtems_filesystem_location_info_t *pathloc);
/**
* @brief Routine for node creation in a MSDOS filesystem.
*
* MSDOS Directory Handlers Implementation
*/
int msdos_mknod(
const rtems_filesystem_location_info_t *loc,
const char *name,
size_t namelen,
mode_t mode,
dev_t dev
);
/**
* @brief Remove node from MSDOS directory.
*
* MSDOS Directory Handlers Implementation
*/
int msdos_rmnod(
const rtems_filesystem_location_info_t *parentloc,
const rtems_filesystem_location_info_t *loc
);
/**
* @brief Rename a MSDOS filesystem node.
*
* Routine to rename a MSDOS filesystem node
*/
int msdos_rename(
const rtems_filesystem_location_info_t *old_parent_loc,
const rtems_filesystem_location_info_t *old_loc,
const rtems_filesystem_location_info_t *new_parent_loc,
const char *new_name,
size_t new_namelen
);
int msdos_statvfs(
const rtems_filesystem_location_info_t *root_loc,
struct statvfs *sb);
void msdos_lock(const rtems_filesystem_mount_table_entry_t *mt_entry);
void msdos_unlock(const rtems_filesystem_mount_table_entry_t *mt_entry);
/**
* @brief MSDOS filesystem initialization routine.
*
* MSDOS Initialization support routine implementation
*/
int msdos_initialize_support(
rtems_filesystem_mount_table_entry_t *temp_mt_entry,
const rtems_filesystem_operations_table *op_table,
const rtems_filesystem_file_handlers_r *file_handlers,
const rtems_filesystem_file_handlers_r *directory_handlers,
rtems_dosfs_convert_control *converter
);
ssize_t msdos_file_read(
rtems_libio_t *iop, /* IN */
void *buffer, /* IN */
size_t count /* IN */
);
ssize_t msdos_file_write(
rtems_libio_t *iop, /* IN */
const void *buffer, /* IN */
size_t count /* IN */
);
int msdos_file_stat(
const rtems_filesystem_location_info_t *loc,
struct stat *buf
);
int
msdos_file_ftruncate(
rtems_libio_t *iop, /* IN */
off_t length /* IN */
);
int msdos_file_sync(rtems_libio_t *iop);
ssize_t msdos_dir_read(
rtems_libio_t *iop, /* IN */
void *buffer, /* IN */
size_t count /* IN */
);
int msdos_dir_sync(rtems_libio_t *iop);
int msdos_dir_stat(
const rtems_filesystem_location_info_t *loc,
struct stat *buf
);
/**
* @brief Implements wake up version of the "signal" operation.
*
* Routine to create a new MSDOS filesystem node
*
*/
int msdos_creat_node(const rtems_filesystem_location_info_t *parent_loc,
fat_file_type_t type,
const char *name,
int name_len,
mode_t mode,
const fat_file_fd_t *link_fd);
/* Misc prototypes */
int msdos_find_name(
rtems_filesystem_location_info_t *parent_loc,
const char *name,
int name_len
);
int msdos_get_name_node(
const rtems_filesystem_location_info_t *parent_loc,
bool create_node,
const char *name,
int name_len,
msdos_name_type_t name_type,
fat_dir_pos_t *dir_pos,
char *name_dir_entry
);
int msdos_dir_info_remove(rtems_filesystem_location_info_t *pathloc);
ssize_t
msdos_format_dirent_with_dot(char *dst,const char *src);
msdos_name_type_t msdos_long_to_short(rtems_dosfs_convert_control *converter,
const char *lfn, int lfn_len,
char* sfn, int sfn_len);
ssize_t
msdos_filename_utf8_to_short_name_for_compare (
rtems_dosfs_convert_control *converter,
const uint8_t *utf8_name,
const size_t utf8_name_size,
void *short_name,
const size_t short_name_size);
ssize_t
msdos_filename_utf8_to_short_name_for_save (
rtems_dosfs_convert_control *converter,
const uint8_t *utf8_name,
const size_t utf8_name_size,
void *short_name,
const size_t short_name_size);
ssize_t
msdos_filename_utf8_to_long_name_for_compare (
rtems_dosfs_convert_control *converter,
const uint8_t *utf8_name,
const size_t utf8_name_size,
uint8_t *long_name,
const size_t long_name_size);
ssize_t
msdos_filename_utf8_to_long_name_for_save (
rtems_dosfs_convert_control *converter,
const uint8_t *utf8_name,
const size_t utf8_name_size,
uint16_t *long_name,
const size_t long_name_size);
ssize_t
msdos_get_utf16_string_from_long_entry (
const char *entry,
uint16_t *entry_string_buf,
const size_t buf_size,
bool is_first_entry
);
void msdos_date_unix2dos(
unsigned int tsp, uint16_t *ddp,
uint16_t *dtp);
unsigned int msdos_date_dos2unix(unsigned int dd, unsigned int dt);
int msdos_set_first_char4file_name(
rtems_filesystem_mount_table_entry_t *mt_entry,
fat_dir_pos_t *dir_pos,
unsigned char first_char
);
int msdos_dir_is_empty(
rtems_filesystem_mount_table_entry_t *mt_entry,
fat_file_fd_t *fat_fd,
bool *ret_val
);
int msdos_find_name_in_fat_file(
rtems_filesystem_mount_table_entry_t *mt_entry,
fat_file_fd_t *fat_fd,
bool create_node,
const uint8_t *name_utf8,
int name_len,
msdos_name_type_t name_type,
fat_dir_pos_t *dir_pos,
char *name_dir_entry
);
int msdos_find_node_by_cluster_num_in_fat_file(
rtems_filesystem_mount_table_entry_t *mt_entry,
fat_file_fd_t *fat_fd,
uint32_t cl4find,
fat_dir_pos_t *dir_pos,
char *dir_entry
);
int msdos_get_dotdot_dir_info_cluster_num_and_offset(
rtems_filesystem_mount_table_entry_t *mt_entry,
uint32_t cln,
fat_dir_pos_t *dir_pos,
char *dir_entry
);
int msdos_sync(rtems_libio_t *iop);
uint8_t msdos_lfn_checksum(const void *entry);
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* __DOSFS_MSDOS_H__ */