source: rtems/cpukit/libfs/src/dosfs/dosfs.h @ 27170bae

4.115
Last change on this file since 27170bae was 27170bae, checked in by Ralf Kirchner <ralf.kirchner@…>, on 05/31/13 at 08:49:59

dosfs: Documentation

  • Property mode set to 100644
File size: 13.4 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.com/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 * @{
193 */
194
195/**
196 * @brief Semaphore count per FAT filesystem instance.
197 *
198 * This can be used for system configuration via <rtems/confdefs.h>.
199 */
200#define RTEMS_DOSFS_SEMAPHORES_PER_INSTANCE 1
201
202/**
203 * @brief FAT filesystem mount options.
204 */
205typedef struct {
206  /**
207   * @brief Converter implementation for new file system instance.
208   *
209   * Before converters have been added to the RTEMS implementation of the FAT
210   * file system, the implementation was:
211   * - Short names were saved in code page format (as is still the case).
212   * - Long names were not saved in UTF-16 format as mandated by the FAT file
213   *   system specification.  Instead the character in the local encoding was
214   *   stored to the low byte directly and the high byte was set to zero.
215   *
216   * There are a few compatibility issues due to a non-standard conform
217   * implementation of the FAT file system before the UTF-8 support was added.
218   * These following issues affect the default converter and the UTF-8
219   * converter:
220   * - Before UTF-8 support was added, it was possible to create files with the
221   *   the same short name in single case and mixed case in a directory.  It
222   *   was for example possible to have files "ABC" and "aBc" in a single
223   *   directory.  Now this bug is fixed.
224   * - Before UTF-8 support was added, it was possible to create files with a
225   *   name length of slightly more than 255 characters.  Now the
226   *   implementation adheres exactly to the 255 character limit.
227   * - Long file names saved before UTF-8 support was added could contain
228   *   non-ASCII characters in the low byte which was saved for a long name
229   *   character.  With the default converter this means such files can be read
230   *   only by their short file name.  With the UTF-8 converter file names will
231   *   be read correctly as long as the characters written with the old
232   *   implementation were Latin-1 characters.
233   *
234   * The following sample code demonstrates how to mount a file
235   * system with UTF-8 support:
236   * @code
237   * #include <errno.h>
238   * #include <assert.h>
239   * #include <rtems/dosfs.h>
240   * #include <rtems/libio.h>
241   *
242   * static int mount_with_utf8(
243   *   const char *device_file,
244   *   const char *mount_point
245   * )
246   * {
247   *   rtems_dosfs_convert_control *convert_ctrl;
248   *   int                          rv;
249   *
250   *   convert_ctrl = rtems_dosfs_create_utf8_converter( "CP850" );
251   *
252   *   if ( convert_ctrl != NULL ) {
253   *     rtems_dosfs_mount_options mount_opts;
254   *
255   *     memset( &mount_opts, 0, sizeof( mount_opts ) );
256   *     mount_opts.converter = convert_ctrl;
257   *
258   *     rv = mount_and_make_target_path(
259   *       device_file,
260   *       mount_point,
261   *       RTEMS_FILESYSTEM_TYPE_DOSFS,
262   *       RTEMS_FILESYSTEM_READ_WRITE,
263   *       &mount_opts
264   *     );
265   *   } else {
266   *     rv = -1;
267   *     errno = ENOMEM;
268   *   }
269   *
270   *   return rv;
271   * }
272   * @endcode
273   *
274   * In case you do not want UTF-8 support, you can simply pass a NULL pointer
275   * to mount_and_make_target_path() respectively to mount() instead of the
276   * mount_opts address.
277   *
278   * @see rtems_dosfs_create_default_converter() and
279   * rtems_dosfs_create_utf8_converter().
280   */
281  rtems_dosfs_convert_control *converter;
282} rtems_dosfs_mount_options;
283
284/**
285 * @brief Allocates and initializes a default converter.
286 *
287 * This default converter will accept only POSIX file names with pure ASCII
288 * characters. This largely corresponds to the file name handling before the
289 * optional UTF-8 support was added to the RTEMS implementation of the FAT file
290 * system.  This handling is mostly backwards compatible to the previous RTEMS
291 * implementation of the FAT file system.
292 *
293 * For backwards compatibility and the previous RTEMS implementation of the FAT
294 * file system please see also @ref rtems_dosfs_mount_options and mount().
295 *
296 * @retval NULL Something failed.
297 * @retval other Pointer to initialized converter.
298 */
299rtems_dosfs_convert_control *rtems_dosfs_create_default_converter(void);
300
301/**
302 * @brief Allocates and initializes a UTF-8 converter.
303 *
304 * This converter will assume that all file names passed to POSIX file handling
305 * methods are UTF-8 strings and will convert them to the selected code page
306 * for short file names and to UTF-16 for long file names.  This conversion
307 * will be done during reading and writing.  These conversions correspond to
308 * the specification of the FAT file system.  This handling is mostly backwards
309 * compatible to the previous RTEMS implementation of the FAT file system.
310 *
311 * For backwards compatibility and the previous RTEMS implementation of the FAT
312 * file system please see also @ref rtems_dosfs_mount_options and mount().
313 *
314 * One possible issue with this converter is: When reading file names which
315 * have been created with other implementations of the FAT file system, it can
316 * happen that during the conversion to UTF-8 a long file name becomes longer
317 * and exceeds the 255 bytes limit.  In such a case only the short file name
318 * will get read.
319 *
320 * @param[in] codepage The iconv() identification string for the used code
321 * page.
322 *
323 * @retval NULL Something failed.
324 * @retval other Pointer to initialized converter.
325 */
326rtems_dosfs_convert_control *rtems_dosfs_create_utf8_converter(
327  const char *codepage
328);
329
330#define MSDOS_FMT_INFO_LEVEL_NONE   (0)
331#define MSDOS_FMT_INFO_LEVEL_INFO   (1)
332#define MSDOS_FMT_INFO_LEVEL_DETAIL (2)
333#define MSDOS_FMT_INFO_LEVEL_DEBUG  (3)
334
335/**
336 * @brief FAT file system format request parameters.
337 */
338typedef struct {
339  /**
340   * @brief OEM name string or NULL.
341   */
342  const char *OEMName;
343
344  /**
345   * @brief Volume label string or NULL.
346   */
347  const char *VolLabel;
348
349  /**
350   * @brief Sectors per cluster hint.
351   *
352   * The format procedure may choose another value.  Use 0 as default value.
353   */
354  uint32_t sectors_per_cluster;
355
356  /**
357   * @brief Number of FATs hint.
358   *
359   * Use 0 as default value.
360   */
361  uint32_t fat_num;
362
363  /**
364   * @brief Minimum files in root directory for FAT12 and FAT16.
365   *
366   * The format procedure may choose a greater value.  Use 0 as default value.
367   */
368  uint32_t files_per_root_dir;
369
370  /**
371   * @brief Media code.
372   *
373   * Use 0 as default value.  The default media code is 0xf8.
374   */
375  uint8_t media;
376
377  /**
378   * @brief Quick format.
379   *
380   * If set to true, then do not clear data sectors to zero.
381   */
382  bool quick_format;
383
384  /**
385   * @brief Do not align FAT, data cluster, and root directory to a cluster
386   * boundary.
387   */
388  bool skip_alignment;
389
390  /**
391   * @brief Synchronize device after write operations.
392   */
393  bool sync_device;
394
395  /**
396   * @brief The amount of info to output.
397   */
398  int info_level;
399} msdos_format_request_param_t;
400
401/**
402 * @brief Formats a block device with a FAT file system.
403 *
404 * @param[in] devname The block device path.
405 * @param[in] rqdata The FAT file system format request data.  Use NULL for
406 * default parameters.
407 *
408 * @retval 0 Successful operation.
409 * @retval -1 An error occurred.  The @c errno indicates the error.
410 */
411int msdos_format (
412  const char *devname,
413  const msdos_format_request_param_t *rqdata
414);
415
416/** @} */
417
418int rtems_dosfs_initialize(rtems_filesystem_mount_table_entry_t *mt_entry,
419                           const void                           *data);
420
421#ifdef __cplusplus
422}
423#endif
424
425#endif
Note: See TracBrowser for help on using the repository browser.