239
208
return FAT_DENTRY_VALID;
211
/** Compute checksum of Node name.
213
* Returns an unsigned byte checksum computed on an unsigned byte
214
* array. The array must be 11 bytes long and is assumed to contain
215
* a name stored in the format of a MS-DOS directory entry.
217
* @param name Node name read from the dentry.
219
* @return An 8-bit unsigned checksum of the name.
221
uint8_t fat_dentry_chksum(uint8_t *name)
225
for (i = 0; i < (FAT_NAME_LEN + FAT_EXT_LEN); i++)
226
sum = ((sum & 1) ? 0x80 : 0) + (sum >> 1) + name[i];
231
/** Get number of bytes in a string with size limit.
233
* @param str NULL-terminated (or not) string.
234
* @param size Maximum number of bytes to consider.
236
* @return Number of bytes in string (without 0 and ff).
239
size_t fat_lfn_str_nlength(const uint16_t *str, size_t size)
243
while (offset < size) {
244
if (str[offset] == 0 || str[offset] == FAT_LFN_PAD)
251
/** Get number of bytes in a FAT long entry occuped by characters.
253
* @param d FAT long entry.
255
* @return Number of bytes.
258
size_t fat_lfn_size(const fat_dentry_t *d)
262
size += fat_lfn_str_nlength(FAT_LFN_PART1(d), FAT_LFN_PART1_SIZE);
263
size += fat_lfn_str_nlength(FAT_LFN_PART2(d), FAT_LFN_PART2_SIZE);
264
size += fat_lfn_str_nlength(FAT_LFN_PART3(d), FAT_LFN_PART3_SIZE);
269
size_t fat_lfn_get_entry(const fat_dentry_t *d, uint16_t *dst, size_t *offset)
272
for (i = FAT_LFN_PART3_SIZE - 1; i >= 0 && *offset > 0; i--) {
273
if (d->lfn.part3[i] == 0 || d->lfn.part3[i] == FAT_LFN_PAD)
276
dst[(*offset)] = uint16_t_le2host(d->lfn.part3[i]);
278
for (i = FAT_LFN_PART2_SIZE - 1; i >= 0 && *offset > 0; i--) {
279
if (d->lfn.part2[i] == 0 || d->lfn.part2[i] == FAT_LFN_PAD)
282
dst[(*offset)] = uint16_t_le2host(d->lfn.part2[i]);
284
for (i = FAT_LFN_PART1_SIZE - 1; i >= 0 && *offset > 0; i--) {
285
if (d->lfn.part1[i] == 0 || d->lfn.part1[i] == FAT_LFN_PAD)
288
dst[(*offset)] = uint16_t_le2host(d->lfn.part1[i]);
293
size_t fat_lfn_set_entry(const uint16_t *src, size_t *offset, size_t size,
297
for (idx = 0; idx < FAT_LFN_PART1_SIZE; idx++) {
298
if (*offset < size) {
299
d->lfn.part1[idx] = host2uint16_t_le(src[*offset]);
302
d->lfn.part1[idx] = FAT_LFN_PAD;
304
for (idx = 0; idx < FAT_LFN_PART2_SIZE; idx++) {
305
if (*offset < size) {
306
d->lfn.part2[idx] = host2uint16_t_le(src[*offset]);
309
d->lfn.part2[idx] = FAT_LFN_PAD;
311
for (idx = 0; idx < FAT_LFN_PART3_SIZE; idx++) {
312
if (*offset < size) {
313
d->lfn.part3[idx] = host2uint16_t_le(src[*offset]);
316
d->lfn.part3[idx] = FAT_LFN_PAD;
319
if (src[*offset] == 0)
321
FAT_LFN_ATTR(d) = FAT_ATTR_LFN;
323
d->lfn.firstc_lo = 0;
328
void str_to_ascii(char *dst, const char *src, size_t count, uint8_t pad)
335
if ((ch = str_decode(src, &off, STR_NO_LIMIT)) != 0) {
336
if (ascii_check(ch) & IS_D_CHAR(ch))
349
bool fat_valid_name(const char *name)
355
while ((ch = str_decode(name, &offset, STR_NO_LIMIT)) != 0) {
356
if (str_chr(FAT_STOP_CHARS, ch) != NULL) {
364
bool fat_valid_short_name(const char *name)
367
unsigned int dot = 0;
368
bool dot_found = false;
370
for (i = 0; name[i]; i++) {
371
if (name[i] == '.') {
379
if (!IS_D_CHAR(name[i]))
385
if (dot > FAT_NAME_LEN)
387
if (i - dot > FAT_EXT_LEN + 1)
390
if (i > FAT_NAME_LEN)
397
size_t utf16_length(const uint16_t *wstr)