RTEMS  5.1
msdos.h
Go to the documentation of this file.
1 
9 /*
10  * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
11  * Author: Eugeny S. Mints <Eugeny.Mints@oktet.ru>
12  *
13  * Modifications to support UTF-8 in the file system are
14  * Copyright (c) 2013 embedded brains GmbH.
15  *
16  * The license and distribution terms for this file may be
17  * found in the file LICENSE in this distribution or at
18  * http://www.rtems.org/license/LICENSE.
19  */
20 
21 #ifndef __DOSFS_MSDOS_H__
22 #define __DOSFS_MSDOS_H__
23 
24 #include <rtems.h>
25 #include <rtems/libio_.h>
26 #include <rtems/dosfs.h>
27 #include <rtems/thread.h>
28 
29 #include "fat.h"
30 #include "fat_file.h"
31 
38 #ifdef __cplusplus
39 extern "C" {
40 #endif
41 
42 #define MSDOS_NAME_NOT_FOUND_ERR 0x7D01
43 
44 /*
45  * This structure identifies the instance of the filesystem on the MSDOS
46  * level.
47  */
48 typedef struct msdos_fs_info_s
49 {
50  fat_fs_info_t fat; /*
51  * volume
52  * description
53  */
54  const rtems_filesystem_file_handlers_r *directory_handlers; /*
55  * a set of routines
56  * that handles the
57  * nodes of directory
58  * type
59  */
60  const rtems_filesystem_file_handlers_r *file_handlers; /*
61  * a set of routines
62  * that handles the
63  * nodes of file
64  * type
65  */
66  rtems_recursive_mutex vol_mutex;
67  uint8_t *cl_buf; /*
68  * just placeholder
69  * for anything
70  */
71 
72  rtems_dosfs_convert_control *converter;
74 
75 RTEMS_INLINE_ROUTINE void msdos_fs_lock(msdos_fs_info_t *fs_info)
76 {
77  rtems_recursive_mutex_lock(&fs_info->vol_mutex);
78 }
79 
80 RTEMS_INLINE_ROUTINE void msdos_fs_unlock(msdos_fs_info_t *fs_info)
81 {
82  rtems_recursive_mutex_unlock(&fs_info->vol_mutex);
83 }
84 
85 /* a set of routines that handle the nodes which are directories */
86 extern const rtems_filesystem_file_handlers_r msdos_dir_handlers;
87 
88 /* a set of routines that handle the nodes which are files */
89 extern const rtems_filesystem_file_handlers_r msdos_file_handlers;
90 
91 /*
92  * Macros for fetching fields from 32 bytes long FAT Directory Entry
93  * Structure
94  */
95 #define MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE 32 /* 32 bytes */
96 
97 #define MSDOS_DIR_NAME(x) (char *)((x) + 0)
98 #define MSDOS_DIR_ENTRY_TYPE(x) (uint8_t *)((x) + 0)
99 #define MSDOS_DIR_ATTR(x) (uint8_t *)((x) + 11)
100 #define MSDOS_DIR_NT_RES(x) (uint8_t *)((x) + 12)
101 #define MSDOS_DIR_LFN_CHECKSUM(x) (uint8_t *)((x) + 13)
102 #define MSDOS_DIR_CRT_TIME_TENTH(x) (uint8_t *)((x) + 13)
103 #define MSDOS_DIR_CRT_TIME(x) (uint16_t *)((x) + 14)
104 #define MSDOS_DIR_CRT_DATE(x) (uint16_t *)((x) + 16)
105 #define MSDOS_DIR_LAST_ACCESS_DATE(x) (uint16_t *)((x) + 18)
106 #define MSDOS_DIR_FIRST_CLUSTER_HI(x) (uint16_t *)((x) + 20)
107 #define MSDOS_DIR_WRITE_TIME(x) (uint16_t *)((x) + 22)
108 #define MSDOS_DIR_WRITE_DATE(x) (uint16_t *)((x) + 24)
109 #define MSDOS_DIR_FIRST_CLUSTER_LOW(x) (uint16_t *)((x) + 26)
110 #define MSDOS_DIR_FILE_SIZE(x) (uint32_t *)((x) + 28)
111 
112 #define MSDOS_EXTRACT_CLUSTER_NUM(p) \
113  (uint32_t)( (CF_LE_W(*MSDOS_DIR_FIRST_CLUSTER_LOW(p))) | \
114  ((uint32_t)(CF_LE_W((*MSDOS_DIR_FIRST_CLUSTER_HI(p))))<<16) )
115 
116 /*
117  * Fields offset in 32 bytes long FAT Directory Entry
118  * Structure
119  */
120 #define MSDOS_FILE_SIZE_OFFSET 28
121 #define MSDOS_FILE_NAME_OFFSET 0
122 #define MSDOS_FIRST_CLUSTER_HI_OFFSET 20
123 #define MSDOS_FIRST_CLUSTER_LOW_OFFSET 26
124 #define MSDOS_FILE_WDATE_OFFSET 24
125 #define MSDOS_FILE_WTIME_OFFSET 22
126 #define MSDOS_FILE_ADATE_OFFSET 18
127 #define MSDOS_FILE_CDATE_OFFSET 16
128 #define MSDOS_FILE_CTIME_OFFSET 14
129 
130 /*
131  * Possible values of DIR_Attr field of 32 bytes long FAT Directory Entry
132  * Structure
133  */
134 #define MSDOS_ATTR_READ_ONLY 0x01
135 #define MSDOS_ATTR_HIDDEN 0x02
136 #define MSDOS_ATTR_SYSTEM 0x04
137 #define MSDOS_ATTR_VOLUME_ID 0x08
138 #define MSDOS_ATTR_DIRECTORY 0x10
139 #define MSDOS_ATTR_ARCHIVE 0x20
140 #define MSDOS_ATTR_LFN (MSDOS_ATTR_READ_ONLY | \
141  MSDOS_ATTR_HIDDEN | \
142  MSDOS_ATTR_SYSTEM | \
143  MSDOS_ATTR_VOLUME_ID)
144 #define MSDOS_ATTR_LFN_MASK (MSDOS_ATTR_READ_ONLY | \
145  MSDOS_ATTR_HIDDEN | \
146  MSDOS_ATTR_SYSTEM | \
147  MSDOS_ATTR_VOLUME_ID | \
148  MSDOS_ATTR_DIRECTORY | \
149  MSDOS_ATTR_ARCHIVE)
150 
151 #define MSDOS_LAST_LONG_ENTRY 0x40
152 #define MSDOS_LAST_LONG_ENTRY_MASK 0x3F
153 
154 #define MSDOS_DT_2SECONDS_MASK 0x1F /* seconds divided by 2 */
155 #define MSDOS_DT_2SECONDS_SHIFT 0
156 #define MSDOS_DT_MINUTES_MASK 0x7E0 /* minutes */
157 #define MSDOS_DT_MINUTES_SHIFT 5
158 #define MSDOS_DT_HOURS_MASK 0xF800 /* hours */
159 #define MSDOS_DT_HOURS_SHIFT 11
160 
161 #define MSDOS_DD_DAY_MASK 0x1F /* day of month */
162 #define MSDOS_DD_DAY_SHIFT 0
163 #define MSDOS_DD_MONTH_MASK 0x1E0 /* month */
164 #define MSDOS_DD_MONTH_SHIFT 5
165 #define MSDOS_DD_YEAR_MASK 0xFE00 /* year - 1980 */
166 #define MSDOS_DD_YEAR_SHIFT 9
167 
168 
169 /*
170  * Possible values of DIR_Name[0] field of 32 bytes long FAT Directory Entry
171  * Structure
172  */
173 #define MSDOS_THIS_DIR_ENTRY_EMPTY 0xE5
174 #define MSDOS_THIS_DIR_ENTRY_AND_REST_EMPTY 0x00
175 
176 /*
177  * Number of characters per directory entry for a long filename.
178  */
179 #define MSDOS_LFN_LEN_PER_ENTRY (13)
180 
181 /*
182  * Macros for names parsing and formatting
183  */
184 #define MSDOS_NAME_MAX_UTF8_BYTES_PER_CHAR 4
185 #define MSDOS_NAME_MIN_UTF8_BYTES_PER_CHAR 1
186 
187 #define MSDOS_SHORT_BASE_LEN 8 /* 8 characters */
188 #define MSDOS_SHORT_EXT_LEN 3 /* 3 characters */
189 #define MSDOS_SHORT_NAME_LEN (MSDOS_SHORT_BASE_LEN+\
190  MSDOS_SHORT_EXT_LEN) /* 11 chars */
191 #define MSDOS_NAME_MAX_LNF_LEN (255)
192 #define MSDOS_NAME_MAX MSDOS_SHORT_NAME_LEN
193 #define MSDOS_NAME_MAX_UTF8_SFN_BYTES (MSDOS_NAME_MAX *\
194  MSDOS_NAME_MAX_UTF8_BYTES_PER_CHAR)
195 #define MSDOS_NAME_MAX_WITH_DOT (MSDOS_NAME_MAX + 1)
196 #define MSDOS_SFN_MAX_WITH_DOT_UTF8_BYTES (MSDOS_NAME_MAX_WITH_DOT *\
197  MSDOS_NAME_MAX_UTF8_BYTES_PER_CHAR)
198 #define MSDOS_NAME_MAX_LFN_WITH_DOT (260)
199 
200 #define MSDOS_NAME_LFN_BYTES_PER_CHAR (2)
201 #define MSDOS_NAME_MAX_LFN_BYTES (MSDOS_NAME_MAX_LFN_WITH_DOT *\
202  MSDOS_NAME_LFN_BYTES_PER_CHAR)
203 #define MSDOS_NAME_MAX_UTF8_LFN_BYTES (MSDOS_NAME_MAX_LFN_WITH_DOT *\
204  MSDOS_NAME_MAX_UTF8_BYTES_PER_CHAR)
205 #define MSDOS_ENTRY_LFN_UTF8_BYTES (MSDOS_LFN_LEN_PER_ENTRY *\
206  MSDOS_NAME_MAX_UTF8_BYTES_PER_CHAR)
207 
208 extern const char *const MSDOS_DOT_NAME; /* ".", padded to MSDOS_NAME chars */
209 extern const char *const MSDOS_DOTDOT_NAME; /* ".", padded to MSDOS_NAME chars */
210 
211 typedef enum msdos_name_types_e
212 {
213  MSDOS_NAME_INVALID = 0, /* Unknown name type. Has invalid characters. */
214  MSDOS_NAME_SHORT, /* Name can be short. */
215  MSDOS_NAME_LONG /* Name is long; cannot be short. */
216 } msdos_name_type_t;
217 
218 typedef enum msdos_token_types_e
219 {
220  MSDOS_NO_MORE_PATH,
221  MSDOS_CURRENT_DIR,
222  MSDOS_UP_DIR,
223  MSDOS_NAME,
224  MSDOS_INVALID_TOKEN
225 } msdos_token_types_t;
226 
227 /* Others macros */
228 #define MSDOS_RES_NT_VALUE 0x00
229 #define MSDOS_INIT_DIR_SIZE 0x00
230 
231 /* "dot" entry offset in a directory */
232 #define MSDOS_DOT_DIR_ENTRY_OFFSET 0x00 /* first entry in directory */
233 
234 /* "dotdot" entry offset in a directory */
235 #define MSDOS_DOTDOT_DIR_ENTRY_OFFSET 0x20 /* second entry in directory */
236 
237 /* 'p' should be char* */
238 #define DOT_NODE_P(p) ((char *)(p))
239 #define DOTDOT_NODE_P(p) ((char *)((p) + MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE))
240 
241 /* Size limits for files and directories */
242 #define MSDOS_MAX_DIR_LENGTH 0x200000 /* 2,097,152 bytes */
243 #define MSDOS_MAX_FILE_SIZE 0xFFFFFFFF /* 4 Gb */
244 
245 /*
246  * The number of 32 bytes long FAT Directory Entry
247  * Structures per 512 bytes sector
248  */
249 #define MSDOS_DPS512_NUM 16
250 
257 
258 void msdos_eval_path(rtems_filesystem_eval_path_context_t *ctx);
259 
266 
272 int msdos_mknod(
274  const char *name,
275  size_t namelen,
276  mode_t mode,
277  dev_t dev
278 );
279 
285 int msdos_rmnod(
286  const rtems_filesystem_location_info_t *parentloc,
288 );
289 
295 int msdos_rename(
296  const rtems_filesystem_location_info_t *old_parent_loc,
297  const rtems_filesystem_location_info_t *old_loc,
298  const rtems_filesystem_location_info_t *new_parent_loc,
299  const char *new_name,
300  size_t new_namelen
301 );
302 
303 int msdos_statvfs(
304  const rtems_filesystem_location_info_t *root_loc,
305  struct statvfs *sb);
306 
307 void msdos_lock(const rtems_filesystem_mount_table_entry_t *mt_entry);
308 
309 void msdos_unlock(const rtems_filesystem_mount_table_entry_t *mt_entry);
310 
318  const rtems_filesystem_operations_table *op_table,
319  const rtems_filesystem_file_handlers_r *file_handlers,
320  const rtems_filesystem_file_handlers_r *directory_handlers,
321  rtems_dosfs_convert_control *converter
322 );
323 
324 ssize_t msdos_file_read(
325  rtems_libio_t *iop, /* IN */
326  void *buffer, /* IN */
327  size_t count /* IN */
328 );
329 
330 ssize_t msdos_file_write(
331  rtems_libio_t *iop, /* IN */
332  const void *buffer, /* IN */
333  size_t count /* IN */
334 );
335 
336 int msdos_file_stat(
338  struct stat *buf
339 );
340 
341 int
342 msdos_file_ftruncate(
343  rtems_libio_t *iop, /* IN */
344  off_t length /* IN */
345 );
346 
347 int msdos_file_sync(rtems_libio_t *iop);
348 
349 ssize_t msdos_dir_read(
350  rtems_libio_t *iop, /* IN */
351  void *buffer, /* IN */
352  size_t count /* IN */
353 );
354 
355 int msdos_dir_sync(rtems_libio_t *iop);
356 
357 int msdos_dir_stat(
359  struct stat *buf
360 );
361 
369  fat_file_type_t type,
370  const char *name,
371  int name_len,
372  mode_t mode,
373  const fat_file_fd_t *link_fd);
374 
375 /* Misc prototypes */
376 
377 int msdos_find_name(
379  const char *name,
380  int name_len
381 );
382 
383 int msdos_get_name_node(
384  const rtems_filesystem_location_info_t *parent_loc,
385  bool create_node,
386  const char *name,
387  int name_len,
388  msdos_name_type_t name_type,
389  fat_dir_pos_t *dir_pos,
390  char *name_dir_entry
391 );
392 
393 int msdos_dir_info_remove(rtems_filesystem_location_info_t *pathloc);
394 
395 ssize_t
396 msdos_format_dirent_with_dot(char *dst,const char *src);
397 
398 msdos_name_type_t msdos_long_to_short(rtems_dosfs_convert_control *converter,
399  const char *lfn, int lfn_len,
400  char* sfn, int sfn_len);
401 
402 ssize_t
403 msdos_filename_utf8_to_short_name_for_compare (
404  rtems_dosfs_convert_control *converter,
405  const uint8_t *utf8_name,
406  const size_t utf8_name_size,
407  void *short_name,
408  const size_t short_name_size);
409 
410 ssize_t
411 msdos_filename_utf8_to_short_name_for_save (
412  rtems_dosfs_convert_control *converter,
413  const uint8_t *utf8_name,
414  const size_t utf8_name_size,
415  void *short_name,
416  const size_t short_name_size);
417 
418 ssize_t
419 msdos_filename_utf8_to_long_name_for_compare (
420  rtems_dosfs_convert_control *converter,
421  const uint8_t *utf8_name,
422  const size_t utf8_name_size,
423  uint8_t *long_name,
424  const size_t long_name_size);
425 
426 ssize_t
427 msdos_filename_utf8_to_long_name_for_save (
428  rtems_dosfs_convert_control *converter,
429  const uint8_t *utf8_name,
430  const size_t utf8_name_size,
431  uint16_t *long_name,
432  const size_t long_name_size);
433 
434 ssize_t
435 msdos_get_utf16_string_from_long_entry (
436  const char *entry,
437  uint16_t *entry_string_buf,
438  const size_t buf_size,
439  bool is_first_entry
440 );
441 
442 void msdos_date_unix2dos(
443  unsigned int tsp, uint16_t *ddp,
444  uint16_t *dtp);
445 
446 unsigned int msdos_date_dos2unix(unsigned int dd, unsigned int dt);
447 
448 int msdos_set_first_char4file_name(
450  fat_dir_pos_t *dir_pos,
451  unsigned char first_char
452 );
453 
454 int msdos_dir_is_empty(
456  fat_file_fd_t *fat_fd,
457  bool *ret_val
458 );
459 
460 int msdos_find_name_in_fat_file(
462  fat_file_fd_t *fat_fd,
463  bool create_node,
464  const uint8_t *name_utf8,
465  int name_len,
466  msdos_name_type_t name_type,
467  fat_dir_pos_t *dir_pos,
468  char *name_dir_entry
469 );
470 
471 int msdos_find_node_by_cluster_num_in_fat_file(
473  fat_file_fd_t *fat_fd,
474  uint32_t cl4find,
475  fat_dir_pos_t *dir_pos,
476  char *dir_entry
477 );
478 
479 int msdos_get_dotdot_dir_info_cluster_num_and_offset(
481  uint32_t cln,
482  fat_dir_pos_t *dir_pos,
483  char *dir_entry
484 );
485 
486 int msdos_sync(rtems_libio_t *iop);
487 
488 uint8_t msdos_lfn_checksum(const void *entry);
489 
490 #ifdef __cplusplus
491 }
492 #endif
493 
494 #endif /* __DOSFS_MSDOS_H__ */
Definition: msdos.h:48
Definition: fat.h:380
int msdos_mknod(const rtems_filesystem_location_info_t *loc, const char *name, size_t namelen, mode_t mode, dev_t dev)
Routine for node creation in a MSDOS filesystem.
Definition: msdos_mknod.c:38
Constants/Data Structures/Prototypes for Operations on "fat-file".
int msdos_rmnod(const rtems_filesystem_location_info_t *parentloc, const rtems_filesystem_location_info_t *loc)
Remove node from MSDOS directory.
Definition: msdos_rmnod.c:25
void msdos_free_node_info(const rtems_filesystem_location_info_t *pathloc)
Call the Fat-File close routine.
Definition: msdos_free.c:37
FAT filesystem convert control.
Definition: dosfs.h:182
File system node operations table.
Definition: libio.h:1005
Definition: fat.h:351
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)
MSDOS filesystem initialization routine.
Definition: msdos_initsupp.c:52
void msdos_shut_down(rtems_filesystem_mount_table_entry_t *temp_mt_entry)
Shut down the MSDOS filesystem.
Definition: msdos_fsunmount.c:47
Descriptor of a fat-file.
Definition: fat_file.h:73
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)
Implements wake up version of the "signal" operation.
Definition: msdos_create.c:62
Mount table entry.
Definition: libio.h:1604
Application Interface to FAT Filesystem.
File system operations table.
Definition: libio.h:472
LibIO Internal Interface.
Path evaluation context.
Definition: libio.h:84
An open file data structure.
Definition: libio.h:1320
Definition: statvfs.h:35
Definition: mmu-config.c:40
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)
Rename a MSDOS filesystem node.
Definition: msdos_rename.c:39
#define RTEMS_INLINE_ROUTINE
Definition: basedefs.h:66
Constants/Data Structures/Prototypes on a Volume with FAT Filesystem.
File system location.
Definition: fs.h:53