source: rtems/cpukit/libfs/src/dosfs/dosfs.h @ 665f03a

5
Last change on this file since 665f03a was cc69334f, checked in by Joel Sherrill <joel.sherrill@…>, on 03/06/15 at 16:35:40

Fix a number of minor Doxygen formatting issues

  • Property mode set to 100644
File size: 13.7 KB
Line 
1/**
2 * @file
3 *
4 * @brief Application Interface to FAT Filesystem
5 *
6 * @ingroup DOSFS
7 */
8
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 _RTEMS_DOSFS_H
22#define _RTEMS_DOSFS_H
23
24#include <rtems.h>
25#include <rtems/libio.h>
26
27#ifdef __cplusplus
28extern "C" {
29#endif
30
31typedef struct rtems_dosfs_convert_control rtems_dosfs_convert_control;
32
33/**
34 * @brief Converts from UTF-8 into a specific code page.
35 *
36 * @param[in,out] self The convert control.
37 * @param[in] src A well-formed UTF-8 string to be converted.
38 * @param[in] src_size The size of the string in bytes (inludes '\\0' if any).
39 * @param[out] dst The address the converted string will get copied to.
40 * @param[in,out] dst_size The size of the buffer in bytes respectively the
41 * number of bytes written to the buffer.
42 *
43 * @retval 0 Successful operation.
44 * @retval EINVAL Conversion was successful, but is not reversible.
45 * @retval ENOMEM Conversion failed (possibly due to insufficient buffer size).
46 */
47typedef int (*rtems_dosfs_utf8_to_codepage)(
48  rtems_dosfs_convert_control *self,
49  const uint8_t               *src,
50  size_t                       src_size,
51  char                        *dst,
52  size_t                      *dst_size
53);
54
55/**
56 * @brief Converts from a specific code page into UTF-8
57 *
58 * @param[in,out] self The convert control.
59 * @param[in] src A well-formed string in code page format.
60 * @param[in] src_size The size of the string in bytes (inludes '\\0' if any).
61 * @param[out] dst The address the converted string will get copied to.
62 * @param[in,out] dst_size The size of the buffer in bytes respectively the
63 * number of bytes written to the buffer.
64 *
65 * @retval 0 Successful operation.
66 * @retval EINVAL Conversion was successful, but is not reversible.
67 * @retval ENOMEM Conversion failed (possibly due to insufficient buffer size).
68 */
69typedef int (*rtems_dosfs_codepage_to_utf8)(
70  rtems_dosfs_convert_control *self,
71  const char                  *src,
72  size_t                       src_size,
73  uint8_t                     *dst,
74  size_t                      *dst_size
75);
76
77/**
78 * @brief Converts from UTF-8 to UTF-16
79 *
80 * @param[in,out] self The convert control.
81 * @param[in] src A well-formed UTF-8 string to be converted.
82 * @param[in] src_size The size of the string in bytes (inludes '\\0' if any).
83 * @param[out] dst The address the converted string will get copied to
84 * @param[in,out] dst_size The size of the buffer in bytes respectively the
85 * number of bytes written to the buffer.
86 *
87 * @retval 0 Successful operation.
88 * @retval EINVAL Conversion was successful, but is not reversible.
89 * @retval ENOMEM Conversion failed (possibly due to insufficient buffer size).
90 */
91typedef int (*rtems_dosfs_utf8_to_utf16)(
92  rtems_dosfs_convert_control *self,
93  const uint8_t               *src,
94  size_t                       src_size,
95  uint16_t                    *dst,
96  size_t                      *dst_size
97);
98
99/**
100 * @brief Converts from UTF-16 to UTF-8.
101 *
102 * @param[in,out] self The convert control.
103 * @param[in] src A well-formed UTF-16 string to be converted.
104 * @param[in] src_size The size of the string in bytes (inludes '\\0' if any).
105 * @param[out] dst The address the converted string will get copied to.
106 * @param[in,out] dst_size The size of the buffer in bytes respectively the
107 * number of bytes written to the buffer
108 *
109 * @retval 0 Successful operation.
110 * @retval EINVAL Conversion was successful, but is not reversible.
111 * @retval ENOMEM Conversion failed (possibly due to insufficient buffer size).
112 */
113typedef int (*rtems_dosfs_utf16_to_utf8)(
114  rtems_dosfs_convert_control *self,
115  const uint16_t              *src,
116  size_t                       src_size,
117  uint8_t                     *dst,
118  size_t                      *dst_size
119);
120
121/**
122 * @brief Converts from UTF-8 to Normalized Form Canonical Decomposition.
123 *
124 * Does canonical decomposition of the UTF-8 string and in addition
125 * also converts upper case alphabetic characters to lower case characters
126 *
127 * @param[in,out] self The convert control.
128 * @param[in] src A well-formed UTF-8 string to be normalized and fold.
129 * @param[in] src_size The size of the string in bytes (inludes '\\0' if any).
130 * @param[out] dst The address the normalized and fold string will get
131 * copied to.
132 * @param[in,out] dst_size The size of the buffer in bytes respectively the
133 * number of bytes written to the buffer.
134 *
135 * @retval 0 Successful operation.
136 * @retval EINVAL Conversion failed.
137 * @retval ENOMEM Conversion failed (possibly due to insufficient buffer size).
138 * @retval EOVERFLOW Conversion failed.
139 * @retval ENOENT Conversion failed.
140 */
141typedef int (*rtems_dosfs_utf8_normalize_and_fold)(
142  rtems_dosfs_convert_control *self,
143  const uint8_t               *src,
144  size_t                       src_size,
145  uint8_t                     *dst,
146  size_t                      *dst_size
147);
148
149/**
150 * @brief Destroys a convert control structure.
151 *
152 * @param[in,out] self The convert control for destruction.
153 */
154typedef void (*rtems_dosfs_convert_destroy)(
155  rtems_dosfs_convert_control *self
156);
157
158/**
159 * @brief FAT filesystem convert handler.
160 */
161typedef struct {
162  rtems_dosfs_utf8_to_codepage        utf8_to_codepage;
163  rtems_dosfs_codepage_to_utf8        codepage_to_utf8;
164  rtems_dosfs_utf8_to_utf16           utf8_to_utf16;
165  rtems_dosfs_utf16_to_utf8           utf16_to_utf8;
166  rtems_dosfs_utf8_normalize_and_fold utf8_normalize_and_fold;
167  rtems_dosfs_convert_destroy         destroy;
168} rtems_dosfs_convert_handler;
169
170typedef struct {
171  void   *data;
172  size_t  size;
173} rtems_dosfs_buffer;
174
175/**
176 * @brief FAT filesystem convert control.
177 *
178 * Short file names are stored in the code page format.  Long file names are
179 * stored as little-endian UTF-16.  The convert control determines the format
180 * conversions to and from the POSIX file name strings.
181 */
182struct rtems_dosfs_convert_control {
183  const rtems_dosfs_convert_handler *handler;
184  rtems_dosfs_buffer                 buffer;
185};
186
187/**
188 * @defgroup DOSFS FAT Filesystem Support
189 *
190 * @ingroup FileSystemTypesAndMount
191 *
192 * @brief FAT file system configuration support, format and mount options.
193 *
194 * A block device can be formatted with a FAT file system with the
195 * msdos_format() function.
196 *
197 * The FAT file system mount operation can be controlled with FAT file system
198 * specific mount options, see @ref rtems_dosfs_mount_options.
199 *
200 * @{
201 */
202
203/**
204 * @brief Semaphore count per FAT filesystem instance.
205 *
206 * This can be used for system configuration via <rtems/confdefs.h>.
207 */
208#define RTEMS_DOSFS_SEMAPHORES_PER_INSTANCE 1
209
210/**
211 * @brief FAT filesystem mount options.
212 */
213typedef struct {
214  /**
215   * @brief Converter implementation for new file system instance.
216   *
217   * Before converters have been added to the RTEMS implementation of the FAT
218   * file system, the implementation was:
219   * - Short names were saved in code page format (as is still the case).
220   * - Long names were not saved in UTF-16 format as mandated by the FAT file
221   *   system specification.  Instead the character in the local encoding was
222   *   stored to the low byte directly and the high byte was set to zero.
223   *
224   * There are a few compatibility issues due to a non-standard conform
225   * implementation of the FAT file system before the UTF-8 support was added.
226   * These following issues affect the default converter and the UTF-8
227   * converter:
228   * - Before UTF-8 support was added, it was possible to create files with the
229   *   the same short name in single case and mixed case in a directory.  It
230   *   was for example possible to have files "ABC" and "aBc" in a single
231   *   directory.  Now this bug is fixed.
232   * - Before UTF-8 support was added, it was possible to create files with a
233   *   name length of slightly more than 255 characters.  Now the
234   *   implementation adheres exactly to the 255 character limit.
235   * - Long file names saved before UTF-8 support was added could contain
236   *   non-ASCII characters in the low byte which was saved for a long name
237   *   character.  With the default converter this means such files can be read
238   *   only by their short file name.  With the UTF-8 converter file names will
239   *   be read correctly as long as the characters written with the old
240   *   implementation were Latin-1 characters.
241   *
242   * The following sample code demonstrates how to mount a file
243   * system with UTF-8 support:
244   * @code
245   * #include <errno.h>
246   * #include <assert.h>
247   * #include <rtems/dosfs.h>
248   * #include <rtems/libio.h>
249   *
250   * static int mount_with_utf8(
251   *   const char *device_file,
252   *   const char *mount_point
253   * )
254   * {
255   *   rtems_dosfs_convert_control *convert_ctrl;
256   *   int                          rv;
257   *
258   *   convert_ctrl = rtems_dosfs_create_utf8_converter( "CP850" );
259   *
260   *   if ( convert_ctrl != NULL ) {
261   *     rtems_dosfs_mount_options mount_opts;
262   *
263   *     memset( &mount_opts, 0, sizeof( mount_opts ) );
264   *     mount_opts.converter = convert_ctrl;
265   *
266   *     rv = mount_and_make_target_path(
267   *       device_file,
268   *       mount_point,
269   *       RTEMS_FILESYSTEM_TYPE_DOSFS,
270   *       RTEMS_FILESYSTEM_READ_WRITE,
271   *       &mount_opts
272   *     );
273   *   } else {
274   *     rv = -1;
275   *     errno = ENOMEM;
276   *   }
277   *
278   *   return rv;
279   * }
280   * @endcode
281   *
282   * In case you do not want UTF-8 support, you can simply pass a NULL pointer
283   * to mount_and_make_target_path() respectively to mount() instead of the
284   * mount_opts address.
285   *
286   * @see rtems_dosfs_create_default_converter() and
287   * rtems_dosfs_create_utf8_converter().
288   */
289  rtems_dosfs_convert_control *converter;
290} rtems_dosfs_mount_options;
291
292/**
293 * @brief Allocates and initializes a default converter.
294 *
295 * This default converter will accept only POSIX file names with pure ASCII
296 * characters. This largely corresponds to the file name handling before the
297 * optional UTF-8 support was added to the RTEMS implementation of the FAT file
298 * system.  This handling is mostly backwards compatible to the previous RTEMS
299 * implementation of the FAT file system.
300 *
301 * For backwards compatibility and the previous RTEMS implementation of the FAT
302 * file system please see also @ref rtems_dosfs_mount_options and mount().
303 *
304 * @retval NULL Something failed.
305 * @retval other Pointer to initialized converter.
306 */
307rtems_dosfs_convert_control *rtems_dosfs_create_default_converter(void);
308
309/**
310 * @brief Allocates and initializes a UTF-8 converter.
311 *
312 * This converter will assume that all file names passed to POSIX file handling
313 * methods are UTF-8 strings and will convert them to the selected code page
314 * for short file names and to UTF-16 for long file names.  This conversion
315 * will be done during reading and writing.  These conversions correspond to
316 * the specification of the FAT file system.  This handling is mostly backwards
317 * compatible to the previous RTEMS implementation of the FAT file system.
318 *
319 * For backwards compatibility and the previous RTEMS implementation of the FAT
320 * file system please see also @ref rtems_dosfs_mount_options and mount().
321 *
322 * One possible issue with this converter is: When reading file names which
323 * have been created with other implementations of the FAT file system, it can
324 * happen that during the conversion to UTF-8 a long file name becomes longer
325 * and exceeds the 255 bytes limit.  In such a case only the short file name
326 * will get read.
327 *
328 * @param[in] codepage The iconv() identification string for the used code
329 * page.
330 *
331 * @retval NULL Something failed.
332 * @retval other Pointer to initialized converter.
333 */
334rtems_dosfs_convert_control *rtems_dosfs_create_utf8_converter(
335  const char *codepage
336);
337
338#define MSDOS_FMT_INFO_LEVEL_NONE   (0)
339#define MSDOS_FMT_INFO_LEVEL_INFO   (1)
340#define MSDOS_FMT_INFO_LEVEL_DETAIL (2)
341#define MSDOS_FMT_INFO_LEVEL_DEBUG  (3)
342
343/**
344 * @brief FAT file system format request parameters.
345 */
346typedef struct {
347  /**
348   * @brief OEM name string or NULL.
349   */
350  const char *OEMName;
351
352  /**
353   * @brief Volume label string or NULL.
354   */
355  const char *VolLabel;
356
357  /**
358   * @brief Sectors per cluster hint.
359   *
360   * The format procedure may choose another value.  Use 0 as default value.
361   */
362  uint32_t sectors_per_cluster;
363
364  /**
365   * @brief Number of FATs hint.
366   *
367   * Use 0 as default value.
368   */
369  uint32_t fat_num;
370
371  /**
372   * @brief Minimum files in root directory for FAT12 and FAT16.
373   *
374   * The format procedure may choose a greater value.  Use 0 as default value.
375   */
376  uint32_t files_per_root_dir;
377
378  /**
379   * @brief Media code.
380   *
381   * Use 0 as default value.  The default media code is 0xf8.
382   */
383  uint8_t media;
384
385  /**
386   * @brief Quick format.
387   *
388   * If set to true, then do not clear data sectors to zero.
389   */
390  bool quick_format;
391
392  /**
393   * @brief Do not align FAT, data cluster, and root directory to a cluster
394   * boundary.
395   */
396  bool skip_alignment;
397
398  /**
399   * @brief Synchronize device after write operations.
400   */
401  bool sync_device;
402
403  /**
404   * @brief The amount of info to output.
405   */
406  int info_level;
407} msdos_format_request_param_t;
408
409/**
410 * @brief Formats a block device with a FAT file system.
411 *
412 * @param[in] devname The block device path.
413 * @param[in] rqdata The FAT file system format request data.  Use NULL for
414 * default parameters.
415 *
416 * @retval 0 Successful operation.
417 * @retval -1 An error occurred.  The @c errno indicates the error.
418 */
419int msdos_format (
420  const char *devname,
421  const msdos_format_request_param_t *rqdata
422);
423
424/** @} */
425
426int rtems_dosfs_initialize(rtems_filesystem_mount_table_entry_t *mt_entry,
427                           const void                           *data);
428
429#ifdef __cplusplus
430}
431#endif
432
433#endif
Note: See TracBrowser for help on using the repository browser.