![]() |
|
|||
File indexing completed on 2025-05-11 08:24:13
0001 /* SPDX-License-Identifier: BSD-2-Clause */ 0002 0003 /** 0004 * @file 0005 * 0006 * @brief Application Interface to FAT Filesystem 0007 * 0008 * @ingroup DOSFS 0009 */ 0010 0011 /* 0012 * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia 0013 * Author: Eugeny S. Mints <Eugeny.Mints@oktet.ru> 0014 * 0015 * Modifications to support UTF-8 in the file system are 0016 * Copyright (c) 2013 embedded brains GmbH & Co. KG 0017 * 0018 * Redistribution and use in source and binary forms, with or without 0019 * modification, are permitted provided that the following conditions 0020 * are met: 0021 * 1. Redistributions of source code must retain the above copyright 0022 * notice, this list of conditions and the following disclaimer. 0023 * 2. Redistributions in binary form must reproduce the above copyright 0024 * notice, this list of conditions and the following disclaimer in the 0025 * documentation and/or other materials provided with the distribution. 0026 * 0027 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 0028 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 0029 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 0030 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 0031 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 0032 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 0033 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 0034 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 0035 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 0036 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 0037 * POSSIBILITY OF SUCH DAMAGE. 0038 */ 0039 0040 #ifndef _RTEMS_DOSFS_H 0041 #define _RTEMS_DOSFS_H 0042 0043 #include <rtems.h> 0044 #include <rtems/libio.h> 0045 0046 #ifdef __cplusplus 0047 extern "C" { 0048 #endif 0049 0050 typedef struct rtems_dosfs_convert_control rtems_dosfs_convert_control; 0051 0052 /** 0053 * @brief Converts from UTF-8 into a specific code page. 0054 * 0055 * @param[in,out] self The convert control. 0056 * @param[in] src A well-formed UTF-8 string to be converted. 0057 * @param[in] src_size The size of the string in bytes (inludes '\\0' if any). 0058 * @param[out] dst The address the converted string will get copied to. 0059 * @param[in,out] dst_size The size of the buffer in bytes respectively the 0060 * number of bytes written to the buffer. 0061 * 0062 * @retval 0 Successful operation. 0063 * @retval EINVAL Conversion was successful, but is not reversible. 0064 * @retval ENOMEM Conversion failed (possibly due to insufficient buffer size). 0065 */ 0066 typedef int (*rtems_dosfs_utf8_to_codepage)( 0067 rtems_dosfs_convert_control *self, 0068 const uint8_t *src, 0069 size_t src_size, 0070 char *dst, 0071 size_t *dst_size 0072 ); 0073 0074 /** 0075 * @brief Converts from a specific code page into UTF-8 0076 * 0077 * @param[in,out] self The convert control. 0078 * @param[in] src A well-formed string in code page format. 0079 * @param[in] src_size The size of the string in bytes (inludes '\\0' if any). 0080 * @param[out] dst The address the converted string will get copied to. 0081 * @param[in,out] dst_size The size of the buffer in bytes respectively the 0082 * number of bytes written to the buffer. 0083 * 0084 * @retval 0 Successful operation. 0085 * @retval EINVAL Conversion was successful, but is not reversible. 0086 * @retval ENOMEM Conversion failed (possibly due to insufficient buffer size). 0087 */ 0088 typedef int (*rtems_dosfs_codepage_to_utf8)( 0089 rtems_dosfs_convert_control *self, 0090 const char *src, 0091 size_t src_size, 0092 uint8_t *dst, 0093 size_t *dst_size 0094 ); 0095 0096 /** 0097 * @brief Converts from UTF-8 to UTF-16 0098 * 0099 * @param[in,out] self The convert control. 0100 * @param[in] src A well-formed UTF-8 string to be converted. 0101 * @param[in] src_size The size of the string in bytes (inludes '\\0' if any). 0102 * @param[out] dst The address the converted string will get copied to 0103 * @param[in,out] dst_size The size of the buffer in bytes respectively the 0104 * number of bytes written to the buffer. 0105 * 0106 * @retval 0 Successful operation. 0107 * @retval EINVAL Conversion was successful, but is not reversible. 0108 * @retval ENOMEM Conversion failed (possibly due to insufficient buffer size). 0109 */ 0110 typedef int (*rtems_dosfs_utf8_to_utf16)( 0111 rtems_dosfs_convert_control *self, 0112 const uint8_t *src, 0113 size_t src_size, 0114 uint16_t *dst, 0115 size_t *dst_size 0116 ); 0117 0118 /** 0119 * @brief Converts from UTF-16 to UTF-8. 0120 * 0121 * @param[in,out] self The convert control. 0122 * @param[in] src A well-formed UTF-16 string to be converted. 0123 * @param[in] src_size The size of the string in bytes (inludes '\\0' if any). 0124 * @param[out] dst The address the converted string will get copied to. 0125 * @param[in,out] dst_size The size of the buffer in bytes respectively the 0126 * number of bytes written to the buffer 0127 * 0128 * @retval 0 Successful operation. 0129 * @retval EINVAL Conversion was successful, but is not reversible. 0130 * @retval ENOMEM Conversion failed (possibly due to insufficient buffer size). 0131 */ 0132 typedef int (*rtems_dosfs_utf16_to_utf8)( 0133 rtems_dosfs_convert_control *self, 0134 const uint16_t *src, 0135 size_t src_size, 0136 uint8_t *dst, 0137 size_t *dst_size 0138 ); 0139 0140 /** 0141 * @brief Converts from UTF-8 to Normalized Form Canonical Decomposition. 0142 * 0143 * Does canonical decomposition of the UTF-8 string and in addition 0144 * also converts upper case alphabetic characters to lower case characters 0145 * 0146 * @param[in,out] self The convert control. 0147 * @param[in] src A well-formed UTF-8 string to be normalized and fold. 0148 * @param[in] src_size The size of the string in bytes (inludes '\\0' if any). 0149 * @param[out] dst The address the normalized and fold string will get 0150 * copied to. 0151 * @param[in,out] dst_size The size of the buffer in bytes respectively the 0152 * number of bytes written to the buffer. 0153 * 0154 * @retval 0 Successful operation. 0155 * @retval EINVAL Conversion failed. 0156 * @retval ENOMEM Conversion failed (possibly due to insufficient buffer size). 0157 * @retval EOVERFLOW Conversion failed. 0158 * @retval ENOENT Conversion failed. 0159 */ 0160 typedef int (*rtems_dosfs_utf8_normalize_and_fold)( 0161 rtems_dosfs_convert_control *self, 0162 const uint8_t *src, 0163 size_t src_size, 0164 uint8_t *dst, 0165 size_t *dst_size 0166 ); 0167 0168 /** 0169 * @brief Destroys a convert control structure. 0170 * 0171 * @param[in,out] self The convert control for destruction. 0172 */ 0173 typedef void (*rtems_dosfs_convert_destroy)( 0174 rtems_dosfs_convert_control *self 0175 ); 0176 0177 /** 0178 * @brief FAT filesystem convert handler. 0179 */ 0180 typedef struct { 0181 rtems_dosfs_utf8_to_codepage utf8_to_codepage; 0182 rtems_dosfs_codepage_to_utf8 codepage_to_utf8; 0183 rtems_dosfs_utf8_to_utf16 utf8_to_utf16; 0184 rtems_dosfs_utf16_to_utf8 utf16_to_utf8; 0185 rtems_dosfs_utf8_normalize_and_fold utf8_normalize_and_fold; 0186 rtems_dosfs_convert_destroy destroy; 0187 } rtems_dosfs_convert_handler; 0188 0189 typedef struct { 0190 void *data; 0191 size_t size; 0192 } rtems_dosfs_buffer; 0193 0194 /** 0195 * @brief FAT filesystem convert control. 0196 * 0197 * Short file names are stored in the code page format. Long file names are 0198 * stored as little-endian UTF-16. The convert control determines the format 0199 * conversions to and from the POSIX file name strings. 0200 */ 0201 struct rtems_dosfs_convert_control { 0202 const rtems_dosfs_convert_handler *handler; 0203 rtems_dosfs_buffer buffer; 0204 }; 0205 0206 /** 0207 * @defgroup DOSFS FAT Filesystem Support 0208 * 0209 * @ingroup FileSystemTypesAndMount 0210 * 0211 * @brief FAT file system configuration support, format and mount options. 0212 * 0213 * A block device can be formatted with a FAT file system with the 0214 * msdos_format() function. 0215 * 0216 * The FAT file system mount operation can be controlled with FAT file system 0217 * specific mount options, see @ref rtems_dosfs_mount_options. 0218 * 0219 * @{ 0220 */ 0221 0222 /** 0223 * @brief Semaphore count per FAT filesystem instance. 0224 * 0225 * This can be used for system configuration via <rtems/confdefs.h>. 0226 */ 0227 #define RTEMS_DOSFS_SEMAPHORES_PER_INSTANCE 1 0228 0229 /** 0230 * @brief FAT filesystem mount options. 0231 */ 0232 typedef struct { 0233 /** 0234 * @brief Converter implementation for new file system instance. 0235 * 0236 * Note: If you pass a converter to mount, you have to destroy it yourself if 0237 * mount failed. In a good case it is destroyed at unmount. 0238 * 0239 * Before converters have been added to the RTEMS implementation of the FAT 0240 * file system, the implementation was: 0241 * - Short names were saved in code page format (as is still the case). 0242 * - Long names were not saved in UTF-16 format as mandated by the FAT file 0243 * system specification. Instead the character in the local encoding was 0244 * stored to the low byte directly and the high byte was set to zero. 0245 * 0246 * There are a few compatibility issues due to a non-standard conform 0247 * implementation of the FAT file system before the UTF-8 support was added. 0248 * These following issues affect the default converter and the UTF-8 0249 * converter: 0250 * - Before UTF-8 support was added, it was possible to create files with the 0251 * the same short name in single case and mixed case in a directory. It 0252 * was for example possible to have files "ABC" and "aBc" in a single 0253 * directory. Now this bug is fixed. 0254 * - Before UTF-8 support was added, it was possible to create files with a 0255 * name length of slightly more than 255 characters. Now the 0256 * implementation adheres exactly to the 255 character limit. 0257 * - Long file names saved before UTF-8 support was added could contain 0258 * non-ASCII characters in the low byte which was saved for a long name 0259 * character. With the default converter this means such files can be read 0260 * only by their short file name. With the UTF-8 converter file names will 0261 * be read correctly as long as the characters written with the old 0262 * implementation were Latin-1 characters. 0263 * 0264 * The following sample code demonstrates how to mount a file 0265 * system with UTF-8 support: 0266 * @code 0267 * #include <errno.h> 0268 * #include <assert.h> 0269 * #include <rtems/dosfs.h> 0270 * #include <rtems/libio.h> 0271 * 0272 * static int mount_with_utf8( 0273 * const char *device_file, 0274 * const char *mount_point 0275 * ) 0276 * { 0277 * rtems_dosfs_convert_control *convert_ctrl; 0278 * int rv; 0279 * 0280 * convert_ctrl = rtems_dosfs_create_utf8_converter( "CP850" ); 0281 * 0282 * if ( convert_ctrl != NULL ) { 0283 * rtems_dosfs_mount_options mount_opts; 0284 * 0285 * memset( &mount_opts, 0, sizeof( mount_opts ) ); 0286 * mount_opts.converter = convert_ctrl; 0287 * 0288 * rv = mount_and_make_target_path( 0289 * device_file, 0290 * mount_point, 0291 * RTEMS_FILESYSTEM_TYPE_DOSFS, 0292 * RTEMS_FILESYSTEM_READ_WRITE, 0293 * &mount_opts 0294 * ); 0295 * 0296 * if (rv != 0) { 0297 * (*mount_opts.converter->handler->destroy)(mount_opts.converter); 0298 * } 0299 * } else { 0300 * rv = -1; 0301 * errno = ENOMEM; 0302 * } 0303 * 0304 * return rv; 0305 * } 0306 * @endcode 0307 * 0308 * In case you do not want UTF-8 support, you can simply pass a NULL pointer 0309 * to mount_and_make_target_path() respectively to mount() instead of the 0310 * mount_opts address. 0311 * 0312 * @see rtems_dosfs_create_default_converter() and 0313 * rtems_dosfs_create_utf8_converter(). 0314 */ 0315 rtems_dosfs_convert_control *converter; 0316 } rtems_dosfs_mount_options; 0317 0318 /** 0319 * @brief Allocates and initializes a default converter. 0320 * 0321 * This default converter will accept only POSIX file names with pure ASCII 0322 * characters. This largely corresponds to the file name handling before the 0323 * optional UTF-8 support was added to the RTEMS implementation of the FAT file 0324 * system. This handling is mostly backwards compatible to the previous RTEMS 0325 * implementation of the FAT file system. 0326 * 0327 * For backwards compatibility and the previous RTEMS implementation of the FAT 0328 * file system please see also @ref rtems_dosfs_mount_options and mount(). 0329 * 0330 * @retval NULL Something failed. 0331 * @retval other Pointer to initialized converter. 0332 */ 0333 rtems_dosfs_convert_control *rtems_dosfs_create_default_converter(void); 0334 0335 /** 0336 * @brief Allocates and initializes a UTF-8 converter. 0337 * 0338 * This converter will assume that all file names passed to POSIX file handling 0339 * methods are UTF-8 strings and will convert them to the selected code page 0340 * for short file names and to UTF-16 for long file names. This conversion 0341 * will be done during reading and writing. These conversions correspond to 0342 * the specification of the FAT file system. This handling is mostly backwards 0343 * compatible to the previous RTEMS implementation of the FAT file system. 0344 * 0345 * For backwards compatibility and the previous RTEMS implementation of the FAT 0346 * file system please see also @ref rtems_dosfs_mount_options and mount(). 0347 * 0348 * One possible issue with this converter is: When reading file names which 0349 * have been created with other implementations of the FAT file system, it can 0350 * happen that during the conversion to UTF-8 a long file name becomes longer 0351 * and exceeds the 255 bytes limit. In such a case only the short file name 0352 * will get read. 0353 * 0354 * @param[in] codepage The iconv() identification string for the used code 0355 * page. 0356 * 0357 * @retval NULL Something failed. 0358 * @retval other Pointer to initialized converter. 0359 */ 0360 rtems_dosfs_convert_control *rtems_dosfs_create_utf8_converter( 0361 const char *codepage 0362 ); 0363 0364 #define MSDOS_FMT_INFO_LEVEL_NONE (0) 0365 #define MSDOS_FMT_INFO_LEVEL_INFO (1) 0366 #define MSDOS_FMT_INFO_LEVEL_DETAIL (2) 0367 #define MSDOS_FMT_INFO_LEVEL_DEBUG (3) 0368 0369 /** 0370 * @brief FAT file system format request parameters. 0371 */ 0372 typedef struct { 0373 /** 0374 * @brief OEM name string or NULL. 0375 */ 0376 const char *OEMName; 0377 0378 /** 0379 * @brief Volume label string or NULL. 0380 */ 0381 const char *VolLabel; 0382 0383 /** 0384 * @brief Sectors per cluster hint. 0385 * 0386 * The format procedure may choose another value. Use 0 as default value. 0387 */ 0388 uint32_t sectors_per_cluster; 0389 0390 /** 0391 * @brief Number of FATs hint. 0392 * 0393 * Use 0 as default value. 0394 */ 0395 uint32_t fat_num; 0396 0397 /** 0398 * @brief Minimum files in root directory for FAT12 and FAT16. 0399 * 0400 * The format procedure may choose a greater value. Use 0 as default value. 0401 */ 0402 uint32_t files_per_root_dir; 0403 0404 /** 0405 * @brief Media code. 0406 * 0407 * Use 0 as default value. The default media code is 0xf8. 0408 */ 0409 uint8_t media; 0410 0411 /** 0412 * @brief Quick format. 0413 * 0414 * If set to true, then do not clear data sectors to zero. 0415 */ 0416 bool quick_format; 0417 0418 /** 0419 * @brief Do not align FAT, data cluster, and root directory to a cluster 0420 * boundary. 0421 */ 0422 bool skip_alignment; 0423 0424 /** 0425 * @brief Synchronize device after write operations. 0426 */ 0427 bool sync_device; 0428 0429 /** 0430 * @brief The amount of info to output. 0431 */ 0432 int info_level; 0433 } msdos_format_request_param_t; 0434 0435 /** 0436 * @brief Formats a block device with a FAT file system. 0437 * 0438 * @param[in] devname The block device path. 0439 * @param[in] rqdata The FAT file system format request data. Use NULL for 0440 * default parameters. 0441 * 0442 * @retval 0 Successful operation. 0443 * @retval -1 An error occurred. The @c errno indicates the error. 0444 */ 0445 int msdos_format ( 0446 const char *devname, 0447 const msdos_format_request_param_t *rqdata 0448 ); 0449 0450 /** @} */ 0451 0452 int rtems_dosfs_initialize(rtems_filesystem_mount_table_entry_t *mt_entry, 0453 const void *data); 0454 0455 #ifdef __cplusplus 0456 } 0457 #endif 0458 0459 #endif
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |