|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
Cross-TU helper prototypes for the FAT/exFAT adapter (part A of 2). More...
Go to the source code of this file.
Functions | |
| void | priv_83_to_str (const uint8_t *in11, uint8_t ntres, char *out13) |
| Unpack on-disk 11-byte 8.3 name into NUL-terminated "NAME.EXT". | |
| ra8_err_t | priv_alloc_cluster (const ra8_fs_mount_t *m, uint32_t *out_cluster) |
| Free-cluster scan from the next-free hint, wrapping exactly once. | |
| ra8_err_t | priv_alloc_eoc_cluster (const ra8_fs_mount_t *m, uint32_t *out_c) |
| Allocate a fresh cluster, mark it EOC, and return its number. | |
| ra8_fs_file_t * | priv_alloc_file_slot (void) |
| Allocate a free entry from the file table; returns NULL if full. | |
| char | priv_ascii_upper (char c) |
| Uppercase an ASCII character (others returned unchanged). | |
| void | priv_byte_copy (uint8_t *dst, const uint8_t *src, uint32_t n) |
| Length-checked byte copy used in place of memcpy(). | |
| uint8_t | priv_byte_equal (const uint8_t *a, const uint8_t *b, uint32_t n) |
| Compare two byte buffers for equality (length n). | |
| ra8_err_t | priv_close_locked (ra8_fs_file_t *file) |
| Close an open file – the guarded body of ra8_fs_close(). | |
| uint64_t | priv_cluster_to_lba (const ra8_fs_mount_t *m, uint32_t cluster) |
| Convert a cluster number into its first data-region LBA. | |
| ra8_err_t | priv_dir_find (const ra8_fs_mount_t *m, const dir_loc_t *loc, const uint8_t *name83, uint64_t *out_lba, uint32_t *out_entry_off, uint8_t out_entry[k_ra8_fs_dir_entry_bytes]) |
| Find a directory entry by 8.3 name within a given directory. | |
| ra8_err_t | priv_dir_find_long (const ra8_fs_mount_t *m, const dir_loc_t *loc, const char *want, uint64_t *out_lba, uint32_t *out_entry_off, uint8_t out_entry[k_ra8_fs_dir_entry_bytes]) |
| Find a directory entry by its VFAT long name (case-insensitive). | |
| void | priv_dir_walk_init_loc (const ra8_fs_mount_t *m, const dir_loc_t *loc, dir_walk_t *w) |
| Initialise a directory walker for an arbitrary directory location. | |
| ra8_err_t | priv_dir_walk_next_sector (const ra8_fs_mount_t *m, dir_walk_t *w, uint8_t *out_eod) |
| Advance the walker to the next sector. | |
| uint32_t | priv_entry_first_cluster (const uint8_t *entry) |
| Read the first cluster from a 32-byte directory entry. | |
| void | priv_entry_set_cluster_size (uint8_t *entry, uint32_t cluster, uint32_t size) |
| Patch first-cluster + size back into a 32-byte directory entry. | |
| uint32_t | priv_eoc_write (const ra8_fs_mount_t *m) |
| End-of-chain value to write for this FAT type. | |
| ra8_err_t | priv_exfat_bmp_switch (const ra8_fs_mount_t *m, uint64_t lba, uint64_t *loaded, uint8_t *sec) |
Flush the cached bitmap sector and load lba if it changed. | |
| uint32_t | priv_exfat_csum32 (uint32_t cs, const uint8_t *buf, uint32_t len) |
| exFAT 32-bit rotate-right-add checksum (boot region + up-case table). | |
| ra8_err_t | priv_exfat_find (const ra8_fs_mount_t *m, const exfat_dir_t *dir, const char *path, uint8_t *out_strm, uint8_t *out_attr) |
| Find a name in ONE exFAT directory. | |
| ra8_err_t | priv_exfat_find_bitmap (const ra8_fs_mount_t *m, uint32_t *out_clus, uint32_t *out_len) |
| Locate the allocation-bitmap entry in the exFAT root directory. | |
| ra8_err_t | priv_exfat_format (const ra8_fs_backend_t *backend, uint64_t total_sectors, uint32_t bps, const char *label) |
| Format the backend as a PC-standard partitioned exFAT volume (#102). | |
| ra8_err_t | priv_exfat_listdir (const ra8_fs_mount_t *m, const exfat_dir_t *dir, ra8_fs_listdir_cb_t cb, void *ctx) |
| Enumerate ONE directory of an exFAT volume. | |
| ra8_err_t | priv_exfat_dir_next (const ra8_fs_mount_t *m, exfat_cursor_t *cur, ra8_fs_dirent_t *out, bool *out_entry) |
| Copy the next visible exFAT directory entry from an existing cursor. | |
| uint8_t | priv_exfat_name_chunk_eq (const uint8_t *entry, const uint16_t *name, uint32_t pos, uint32_t nlen) |
| Compare one file-name entry's 15 UTF-16 units against a needle. | |
| uint16_t | priv_exfat_name_hash (const uint16_t *name, uint32_t nlen) |
| Compute the exFAT NameHash for a name in UTF-16 code units. | |
| ra8_err_t | priv_exfat_name_to_units (const ra8_fs_mount_t *m, const char *path, uint16_t *out, uint32_t *out_units) |
| Convert a caller's exFAT name to code units, refusing what will not fold. | |
| ra8_err_t | priv_exfat_needle_units (const ra8_fs_mount_t *m, const char *name, uint16_t *out, uint32_t *out_units, ra8_err_t too_long) |
Convert a leaf name to code units, mapping over-long to too_long. | |
| ra8_err_t | priv_exfat_next_entry (const ra8_fs_mount_t *m, exfat_cursor_t *cur, uint8_t *out) |
| Fetch the next 32-byte directory entry, following the cluster chain. | |
| ra8_err_t | priv_exfat_open (ra8_fs_mount_t *handle, const char *path, ra8_fs_mode_t mode, ra8_fs_file_t **out_file) |
| Open a file (read-only) on a mounted exFAT volume. | |
| ra8_err_t | priv_exfat_rename (const ra8_fs_mount_t *m, const char *old_path, const char *new_path) |
| Rename a root-level file on an exFAT volume, at any storable length. | |
| uint16_t | priv_exfat_set_checksum (const uint8_t *set, uint32_t bytes) |
| Compute the SetChecksum over a built directory entry set. | |
| ra8_err_t | priv_exfat_unlink (const ra8_fs_mount_t *m, const char *path) |
| Delete a file on an exFAT volume, at any depth. | |
| uint16_t | priv_exfat_upcase_unit (uint16_t unit) |
| Fold a UTF-16 code unit through the canonical exFAT up-case table. | |
| uint32_t | priv_exfat_upcase_checksum (void) |
| Rotate-add checksum of the up-case table this build embeds. | |
| void | priv_exfat_upcase_verify (ra8_fs_mount_t *m) |
| Decide whether this build's fold matches the mounted volume's table. | |
Cross-TU helper prototypes for the FAT/exFAT adapter (part A of 2).
The first half of the FAT/exFAT adapter's cross-TU helper prototypes. Each helper is defined static-free in exactly one FAT/exFAT translation unit and called from at least one other. This part covers the alphabetical run from priv_83_to_str() through priv_exfat_upcase_verify(); the remaining helpers live in ra8_fs_fat_protos_b_internal.h. Both are aggregated by the ra8_fs_fat_internal.h umbrella, which every ra8_fs_fat*.c file includes.
This header aggregates each cross-TU helper's full Doxygen contract.
Definition in file ra8_fs_fat_protos_a_internal.h.
| void priv_83_to_str | ( | const uint8_t * | in11, |
| uint8_t | ntres, | ||
| char * | out13 ) |
Unpack on-disk 11-byte 8.3 name into NUL-terminated "NAME.EXT".
Trims trailing space pad in the base portion, restores the 0x05 -> 0xE5 kanji escape, and emits the dot + extension only when the extension is non-empty. The two DIR_NTRes case flags are applied as they are unpacked, so an entry written for data.log – stored upper-case with both flags set – reads back as data.log rather than DATA.LOG. Pass 0 for ntres to get the raw upper-case form.
| [in] | in11 | Packed 11-byte name. |
| [in] | ntres | The entry's DIR_NTRes byte (0 when it has none). |
| [out] | out13 | Buffer of at least 13 bytes (8 + . + 3 + NUL). |
Definition at line 216 of file ra8_fs_fat_name.c.
References internal_case_apply(), k_dir_marker_free_used, k_dir_marker_kanji_e5, k_filename_base_len, k_filename_ext_len, k_ntres_base_lower, and k_ntres_ext_lower.
Referenced by internal_fat_dir_scan_sector(), and internal_listdir_visit_sector().
| ra8_err_t priv_alloc_cluster | ( | const ra8_fs_mount_t * | m, |
| uint32_t * | out_cluster ) |
Free-cluster scan from the next-free hint, wrapping exactly once.
Starts at the mount's next-free hint (priv_alloc_hint_get, seeded from FAT32's FSI_Nxt_Free when that validates) and walks forward for at most count_of_clusters steps, wrapping back to cluster 2 once, so the whole volume is still examined before it is declared full. The FAT entries are read through the one-sector cache, which is what makes a scan cost one block read per 128 clusters on FAT32 instead of one per cluster.
On success the hint moves to the cluster after the one taken and the tracked free count drops by one, so the FSInfo writeback has something true to write.
| [in] | m | Mount providing geometry and backend. |
| [out] | out_cluster | On success, the allocated cluster number. |
| k_ra8_ok | Cluster found; *out_cluster set. |
| k_ra8_err_no_mem | Volume is full – no free clusters. |
| k_ra8_err_* | Backend read failure. |
Definition at line 591 of file ra8_fs_fat.c.
References ra8_fs_mount_t::count_of_clusters, internal_alloc_start(), k_cluster_first_data, k_cluster_free, k_ra8_err_no_mem, k_ra8_ok, priv_alloc_hint_get(), priv_alloc_hint_set(), priv_fat_get(), and priv_free_count_took().
Referenced by priv_alloc_eoc_cluster().
| ra8_err_t priv_alloc_eoc_cluster | ( | const ra8_fs_mount_t * | m, |
| uint32_t * | out_c ) |
Allocate a fresh cluster, mark it EOC, and return its number.
Combines priv_alloc_cluster with a priv_fat_set to the canonical EOC value. Used by the write path when the file chain needs to grow.
| [in] | m | Mount providing FAT access. |
| [out] | out_c | Receives the allocated cluster. |
| k_ra8_ok | Cluster allocated and marked EOC. |
| k_ra8_err_* | Backend or FAT error. |
Definition at line 278 of file ra8_fs_fat_fileio.c.
References k_ra8_ok, priv_alloc_cluster(), priv_eoc_write(), and priv_fat_set().
Referenced by internal_dir_grow(), internal_fat_mkdir(), internal_fat_trunc_extend(), internal_walk_grow(), and internal_write_position().
| ra8_fs_file_t * priv_alloc_file_slot | ( | void | ) |
Allocate a free entry from the file table; returns NULL if full.
Linear scan of s_files for an entry with in_use == 0.
| non-NULL | Pointer to a ra8_fs_file_t with in_use == 0. |
| NULL | File table is full. |
Definition at line 118 of file ra8_fs_fat_mount.c.
References k_ra8_fs_max_files, and s_files.
Referenced by internal_create_new(), internal_exfat_open_created(), internal_exfat_open_found(), internal_open_existing(), and priv_exfat_open().
| char priv_ascii_upper | ( | char | c | ) |
Uppercase an ASCII character (others returned unchanged).
Maps a-z to A-Z; any other byte is returned unchanged.
| [in] | c | Input character. |
| c | The (possibly) uppercased value. |
c is a byte value. c. Definition at line 37 of file ra8_fs_fat_exfat_read.c.
Referenced by priv_exfat_upcase_unit().
| void priv_byte_copy | ( | uint8_t * | dst, |
| const uint8_t * | src, | ||
| uint32_t | n ) |
Length-checked byte copy used in place of memcpy().
Replaces memcpy() so clang-tidy's clang-analyzer-security.insecureAPI checker stays happy. Same effect on -O2 generated code.
| [out] | dst | Destination buffer. |
| [in] | src | Source buffer. |
| [in] | n | Number of bytes to copy. |
Definition at line 110 of file ra8_fs_fat.c.
Referenced by internal_dir_find_long_sector(), internal_exchk_set(), internal_exfat_build_rename_set(), internal_exfat_locate_label(), internal_exfat_match_set(), internal_exfat_read_entry(), internal_exfat_take_set(), internal_exfat_try_set(), internal_fat_find_vol_id(), internal_fmt_boot_prologue(), internal_fmt_build_bpb_f16(), internal_fmt_build_bpb_f32(), internal_get_label_fat(), internal_read_one_chunk(), priv_dir_commit(), priv_dir_find(), priv_exfat_next_entry(), priv_exfat_write_dir_set(), priv_exfat_write_upcase(), priv_fat_sector_read(), priv_fat_sector_wrote(), and priv_write_into_sector().
| uint8_t priv_byte_equal | ( | const uint8_t * | a, |
| const uint8_t * | b, | ||
| uint32_t | n ) |
Compare two byte buffers for equality (length n).
Returns early on first mismatch. Used in place of memcmp().
| [in] | a | First buffer. |
| [in] | b | Second buffer. |
| [in] | n | Number of bytes to compare. |
| 1 | All n bytes equal. |
| 0 | At least one byte differs. |
Definition at line 118 of file ra8_fs_fat.c.
Referenced by internal_label_from_raw(), and priv_dir_find().
| ra8_err_t priv_close_locked | ( | ra8_fs_file_t * | file | ) |
Close an open file – the guarded body of ra8_fs_close().
Carries the whole contract documented for ra8_fs_close() in ra8_fs.h; the public symbol is the wrapper that brackets this call with priv_lock_acquire / priv_lock_release. Exposed across translation units because ra8_fs_write_file()'s guarded body has to reach it without taking the lock a second time.
| [in,out] | file | Handle returned by priv_open_locked / ra8_fs_open(). |
| k_ra8_ok | File closed. |
| k_ra8_err_null_ptr | file was NULL. |
| k_ra8_err_* | The final modification-time stamp or the FSInfo writeback failed; the handle is released anyway. |
Definition at line 543 of file ra8_fs_fat_file.c.
References internal_close_stamp(), k_ra8_err_null_ptr, and k_ra8_ok.
Referenced by internal_write_file_locked(), and ra8_fs_close().
| uint64_t priv_cluster_to_lba | ( | const ra8_fs_mount_t * | m, |
| uint32_t | cluster ) |
Convert a cluster number into its first data-region LBA.
Cluster numbering starts at k_cluster_first_data (= 2).
| [in] | m | Mount providing geometry. |
| [in] | cluster | Cluster number (>= k_cluster_first_data). |
| 0..UINT32_MAX | Computed LBA. |
Definition at line 541 of file ra8_fs_fat.c.
References ra8_fs_mount_t::first_data_lba, k_cluster_first_data, and ra8_fs_mount_t::sectors_per_cluster.
Referenced by internal_dir_cluster_init(), internal_dir_grow(), internal_dir_walk_init_root(), internal_exchk_set(), internal_exfat_dir_alloc(), internal_exfat_read_entry(), internal_exfat_slice_at(), internal_fat_scan_cluster_dir(), internal_read_one_chunk(), internal_space_exfat_free(), internal_trunc_zero_span(), internal_write_stream(), priv_check_exfat(), priv_dir_walk_init_loc(), priv_dir_walk_next_sector(), priv_exfat_bitmap_lba(), priv_exfat_next_entry(), priv_exfat_seal_cluster(), priv_exfat_write_dir_set(), and priv_exfat_zero_cluster().
| ra8_err_t priv_dir_find | ( | const ra8_fs_mount_t * | m, |
| const dir_loc_t * | loc, | ||
| const uint8_t * | name83, | ||
| uint64_t * | out_lba, | ||
| uint32_t * | out_entry_off, | ||
| uint8_t | out_entry[k_ra8_fs_dir_entry_bytes] ) |
Find a directory entry by 8.3 name within a given directory.
Walks the directory loc (root or a subdirectory) and matches on the packed 11-byte name field. Skips LFN entries (attr 0x0F) and deleted slots.
| [in] | m | Mount providing geometry and backend. |
| [in] | loc | Directory to search (root or a subdirectory). |
| [in] | name83 | Packed 11-byte name. |
| [out] | out_lba | Sector containing the entry. |
| [out] | out_entry_off | Byte offset within the sector. |
| [out] | out_entry | 32 bytes of the entry payload. |
| k_ra8_ok | Entry found; out parameters populated. |
| k_ra8_err_not_found | End-of-directory reached without a match. |
| k_ra8_err_* | Backend error. |
Definition at line 911 of file ra8_fs_fat_name.c.
References dir_walk_t::cur_lba, k_dir_marker_free_perm, k_dir_marker_free_used, k_dir_name_field_len, k_dir_off_attr, k_dir_off_name, k_ra8_err_not_found, k_ra8_fs_attr_lfn, k_ra8_fs_dir_entry_bytes, k_ra8_ok, priv_byte_copy(), priv_byte_equal(), priv_dir_eps(), priv_dir_walk_init_loc(), priv_dir_walk_next_sector(), priv_read_sector(), and priv_sec_walk().
Referenced by internal_alias_unique(), internal_setattr_fat(), internal_stat_fat(), internal_utime_fat(), and priv_dir_lookup_any().
| ra8_err_t priv_dir_find_long | ( | const ra8_fs_mount_t * | m, |
| const dir_loc_t * | loc, | ||
| const char * | want, | ||
| uint64_t * | out_lba, | ||
| uint32_t * | out_entry_off, | ||
| uint8_t | out_entry[k_ra8_fs_dir_entry_bytes] ) |
Find a directory entry by its VFAT long name (case-insensitive).
Walks the directory described by loc sector by sector, calling priv_dir_find_long_sector() on each one. LFN chains are carried across sector boundaries via an lfn_state_t accumulator. A leading '/' in want is stripped before matching. Returns on the first name that matches want via priv_name_ieq(), or reports not-found when the end-of-directory marker is reached without a hit. Used as the fallback by ra8_fs_open() when the 8.3 short-name lookup misses, so that files with names longer than 8.3 (e.g. ".epub" four-char extensions) are accessible by their real long name.
| [in] | m | Mount providing geometry and backend. |
| [in] | loc | Directory to search (root or a subdirectory). |
| [in] | want | Requested name (a leading '/' is ignored). |
| [out] | out_lba | Sector containing the matched 8.3 entry. |
| [out] | out_entry_off | Byte offset within the sector. |
| [out] | out_entry | 32 bytes of the matched 8.3 directory entry. |
| k_ra8_ok | Long name matched; out parameters populated. |
| k_ra8_err_not_found | No entry's long name equals want. |
| k_ra8_err_* | Backend read error propagated from priv_read_sector(). |
want is a NUL-terminated ASCII string. want. Definition at line 275 of file ra8_fs_fat_lfn.c.
References dir_walk_t::cur_lba, internal_dir_find_long_sector(), k_lfn_scan_eod, k_lfn_scan_found, k_lfn_write_max, k_ra8_err_no_mem, k_ra8_err_not_found, k_ra8_fs_dir_entry_bytes, k_ra8_ok, priv_dir_walk_init_loc(), priv_dir_walk_next_sector(), priv_lfn_reset(), priv_read_sector(), priv_sec_walk(), and priv_utf8_to_utf16().
Referenced by internal_setattr_fat(), internal_stat_fat(), internal_utime_fat(), and priv_dir_lookup_any().
| void priv_dir_walk_init_loc | ( | const ra8_fs_mount_t * | m, |
| const dir_loc_t * | loc, | ||
| dir_walk_t * | w ) |
Initialise a directory walker for an arbitrary directory location.
Dispatches to priv_dir_walk_init_root for the root, or sets up a plain cluster-chain walk starting at loc->cluster for a subdirectory (the same machinery the FAT32 root uses, so priv_dir_walk_next_sector follows the chain unchanged).
| [in] | m | Mount providing geometry and FAT type. |
| [in] | loc | Directory to walk (root or a subdirectory cluster). |
| [out] | w | Walker cursor to initialise. |
Definition at line 853 of file ra8_fs_fat_name.c.
References dir_loc_t::cluster, dir_walk_t::cluster, dir_walk_t::cluster_hops, dir_walk_t::cur_lba, dir_walk_t::entry_idx, dir_walk_t::fixed_remaining, internal_dir_walk_init_root(), dir_loc_t::is_root, dir_walk_t::is_root_fixed, priv_cluster_to_lba(), and dir_walk_t::sector_in_cluster.
Referenced by internal_dir_collect_chain(), internal_dir_grow(), internal_dir_is_empty(), internal_fat_find_free_root(), internal_fat_find_vol_id(), priv_dir_find(), priv_dir_find_free_run(), and priv_dir_find_long().
| ra8_err_t priv_dir_walk_next_sector | ( | const ra8_fs_mount_t * | m, |
| dir_walk_t * | w, | ||
| uint8_t * | out_eod ) |
Advance the walker to the next sector.
For fixed-region roots simply increments the LBA. For cluster-chain roots advances within the cluster, then follows the FAT chain when the cluster is exhausted.
| [in] | m | Mount providing geometry and backend. |
| [in,out] | w | Walker cursor to advance. |
| [out] | out_eod | Set to 1 if end-of-directory reached, else 0. |
| k_ra8_ok | Walker advanced (or EOD signalled in *out_eod). |
| k_ra8_err_protocol_error | Cluster-chain cycle detected (corrupt FAT). |
| k_ra8_err_* | Backend error from a FAT read. |
Definition at line 869 of file ra8_fs_fat_name.c.
References dir_walk_t::cluster, dir_walk_t::cluster_hops, ra8_fs_mount_t::count_of_clusters, dir_walk_t::cur_lba, dir_walk_t::entry_idx, dir_walk_t::fixed_remaining, dir_walk_t::is_root_fixed, k_ra8_err_protocol_error, k_ra8_ok, priv_cluster_to_lba(), priv_fat_get(), priv_is_eoc(), dir_walk_t::sector_in_cluster, and ra8_fs_mount_t::sectors_per_cluster.
Referenced by internal_dir_collect_chain(), internal_dir_grow(), internal_dir_is_empty(), internal_fat_dir_advance_sector(), internal_fat_find_free_root(), internal_fat_find_vol_id(), internal_slot_advance(), priv_dir_find(), priv_dir_find_free_run(), and priv_dir_find_long().
| uint32_t priv_entry_first_cluster | ( | const uint8_t * | entry | ) |
Read the first cluster from a 32-byte directory entry.
Combines the high and low cluster halves into a single 32-bit value (FAT32 layout; high half is 0 on FAT12/16).
| [in] | entry | 32-byte directory entry. |
| 0..UINT32_MAX | Cluster number. |
Definition at line 27 of file ra8_fs_fat_file.c.
References k_dir_off_fst_clus_hi, k_dir_off_fst_clus_lo, k_shift_two_bytes, and priv_rd16().
Referenced by internal_enter_subdir(), internal_entry_to_stat(), internal_fat_entry(), internal_open_existing(), internal_rmdir_locate(), and internal_unlink_locate().
| void priv_entry_set_cluster_size | ( | uint8_t * | entry, |
| uint32_t | cluster, | ||
| uint32_t | size ) |
Patch first-cluster + size back into a 32-byte directory entry.
Inverse of priv_entry_first_cluster; also writes file size.
| [in,out] | entry | 32-byte directory entry to update. |
| [in] | cluster | New first cluster. |
| [in] | size | New file size in bytes. |
Definition at line 35 of file ra8_fs_fat_file.c.
References k_dir_off_file_size, k_dir_off_fst_clus_hi, k_dir_off_fst_clus_lo, k_shift_two_bytes, k_word_mask, priv_wr16(), and priv_wr32().
Referenced by internal_create_new(), internal_fat_mkdir(), internal_fat_trunc_commit(), internal_pack_dot_entry(), and internal_truncate_existing().
| uint32_t priv_eoc_write | ( | const ra8_fs_mount_t * | m | ) |
End-of-chain value to write for this FAT type.
Returns the canonical EOC value (0xFFF, 0xFFFF, or 0x0FFFFFFF).
| [in] | m | Mount providing the FAT type. |
| k_cluster_eoc_write_fat12 | FAT12 EOC. |
| k_cluster_eoc_write_fat16 | FAT16 EOC. |
| k_cluster_eoc_write_fat32 | FAT32 EOC. |
Definition at line 526 of file ra8_fs_fat.c.
References k_cluster_eoc_write_exfat, k_cluster_eoc_write_fat12, k_cluster_eoc_write_fat16, k_cluster_eoc_write_fat32, k_ra8_fs_type_exfat, k_ra8_fs_type_fat12, k_ra8_fs_type_fat16, and ra8_fs_mount_t::type.
Referenced by internal_exfat_dir_link(), internal_exfat_link_cluster(), internal_exfat_shrink_chain_tail(), internal_fat_trunc_shrink(), and priv_alloc_eoc_cluster().
| ra8_err_t priv_exfat_bmp_switch | ( | const ra8_fs_mount_t * | m, |
| uint64_t | lba, | ||
| uint64_t * | loaded, | ||
| uint8_t * | sec ) |
Flush the cached bitmap sector and load lba if it changed.
Writes the dirty cached sector before reading the newly requested one.
| [in] | m | Mounted exFAT volume. |
| [in] | lba | Bitmap sector wanted next. |
| [in,out] | loaded | Currently-cached LBA (UINT32_MAX if none). |
| [in,out] | sec | Cached sector buffer. |
| k_ra8_ok | sec now holds lba. |
| k_ra8_err_* | Backend read/write failure. |
sec matches loaded on entry. sec holds lba; the previous sector was written if dirty. loaded == lba. Definition at line 192 of file ra8_fs_fat_exfat_write.c.
References k_ra8_ok, priv_read_sector(), and priv_write_sector().
Referenced by priv_exfat_bitmap_clear(), and priv_exfat_bitmap_mark().
| uint32_t priv_exfat_csum32 | ( | uint32_t | cs, |
| const uint8_t * | buf, | ||
| uint32_t | len ) |
exFAT 32-bit rotate-right-add checksum (boot region + up-case table).
Folds len bytes of buf into the running checksum cs with cs = ror1(cs) + byte per the Microsoft exFAT spec (sections 3.4 and 8.2.2). Shared by the boot-region checksum (which folds surrounding byte ranges to skip the three volatile bytes) and the up-case-table checksum.
| [in] | cs | Running checksum (0 to start). |
| [in] | buf | Bytes to fold in. |
| [in] | len | Number of bytes to fold. |
| 0..UINT32_MAX | The rotate-add fold of cs over buf[0..len-1]. |
buf holds at least len bytes. len is the exact byte count of the span to fold. cs, buf, and len. Definition at line 50 of file ra8_fs_fat_exfat_fmt.c.
References k_exfat_fmt_csum_hibit.
Referenced by internal_exfat_write_boot(), internal_exfat_write_boot_tail(), priv_exfat_upcase_checksum(), and priv_exfat_write_upcase().
| ra8_err_t priv_exfat_dir_next | ( | const ra8_fs_mount_t * | m, |
| exfat_cursor_t * | cur, | ||
| ra8_fs_dirent_t * | out, | ||
| bool * | out_entry ) |
Copy the next visible exFAT directory entry from an existing cursor.
Advances the cursor and copies one stable name, attribute mask, and size.
| [in] | m | Mounted exFAT volume. |
| [in,out] | cur | Independent caller-owned directory cursor state. |
| [out] | out | Stable copied entry value. |
| [out] | out_entry | True for one copied entry; false at clean end. |
| k_ra8_ok | One entry was copied or clean end was reached. |
| k_ra8_err_* | Media, entry-set, name, or cursor-bound failure. |
cur was initialized for m. m. out_entry false without exposing sector scratch. Definition at line 786 of file ra8_fs_fat_exfat_mutate.c.
References internal_exfat_list_emit(), k_exfat_entry_bytes, k_exfat_entry_eod, k_exfat_entry_file, k_exfat_scan_limit, k_ra8_err_invalid_size, k_ra8_err_not_found, k_ra8_ok, priv_exfat_next_entry(), and exfat_cursor_t::scanned.
Referenced by priv_exfat_listdir(), and ra8_fs_dir_next().
| ra8_err_t priv_exfat_find | ( | const ra8_fs_mount_t * | m, |
| const exfat_dir_t * | dir, | ||
| const char * | path, | ||
| uint8_t * | out_strm, | ||
| uint8_t * | out_attr ) |
Find a name in ONE exFAT directory.
Streams dir's entries, matching each File entry set against path; stops at end-of-directory, the end of the directory's run, or the scan bound. This is a single-directory lookup, not a path resolver – pass a leaf name and the directory it should be in, or use priv_exfat_lookup, which resolves a whole path and then calls this (#605).
| [in] | m | Mounted exFAT volume. |
| [in] | dir | Directory to search. |
| [in] | path | Target leaf name, UTF-8; leading slashes are skipped. |
| [out] | out_strm | Receives the matched 32-byte Stream-extension entry – first cluster, both lengths and the secondary flags, so a caller decodes the fields it needs rather than every caller paying for another out-parameter. |
| [out] | out_attr | Low byte of the File entry's FileAttributes, which is where k_exfat_attr_directory lives. Callers that act on the entry MUST consult it: a directory answers this lookup exactly like a file, and treating one as a file frees its cluster chain (#604). |
| k_ra8_ok | Entry found; outputs populated. |
| k_ra8_err_not_found | No matching entry in dir. |
| k_ra8_err_* | Backend read failure. |
dir locates an existing directory on this volume. out_strm mirrors the on-disk Stream entry. Definition at line 371 of file ra8_fs_fat_exfat_read.c.
References internal_exfat_match_set(), k_exfat_entry_bytes, k_exfat_entry_eod, k_exfat_entry_file, k_exfat_name_cap, k_exfat_off_file_attr, k_exfat_scan_limit, k_ra8_err_no_mem, k_ra8_err_not_found, k_ra8_ok, priv_exfat_cursor_init(), priv_exfat_name_to_units(), priv_exfat_next_entry(), and exfat_cursor_t::scanned.
Referenced by internal_exfat_mkdir_check(), priv_exfat_lookup(), and priv_exfat_rename().
| ra8_err_t priv_exfat_find_bitmap | ( | const ra8_fs_mount_t * | m, |
| uint32_t * | out_clus, | ||
| uint32_t * | out_len ) |
Locate the allocation-bitmap entry in the exFAT root directory.
Streams the root directory for the 0x81 entry and returns its data run.
| [in] | m | Mounted exFAT volume. |
| [out] | out_clus | First cluster of the allocation bitmap. |
| [out] | out_len | Bitmap length in bytes. |
| k_ra8_ok | Bitmap located. |
| k_ra8_err_not_found | No allocation-bitmap entry. |
| k_ra8_err_* | Backend read failure. |
Definition at line 81 of file ra8_fs_fat_exfat_write.c.
References k_exfat_entry_bitmap, k_exfat_entry_bytes, k_exfat_entry_eod, k_exfat_scan_limit, k_exfat_strm_off_clus, k_exfat_strm_off_dlen, k_ra8_err_not_found, k_ra8_ok, priv_exfat_cursor_init(), priv_exfat_dir_root(), priv_exfat_next_entry(), priv_rd32(), and exfat_cursor_t::scanned.
Referenced by internal_exfat_dir_alloc(), internal_space_exfat_free(), priv_check_exfat(), and priv_exfat_bitmap_lba().
| ra8_err_t priv_exfat_format | ( | const ra8_fs_backend_t * | backend, |
| uint64_t | total_sectors, | ||
| uint32_t | bps, | ||
| const char * | label ) |
Format the backend as a PC-standard partitioned exFAT volume (#102).
Writes a DOS/MBR partition table at LBA 0 with a single type-0x07 (exFAT/NTFS) partition aligned at ::k_exfat_fmt_part_lba, then lays a complete exFAT volume INSIDE that partition: main + backup boot regions with boot checksums (VolumeLength = partition length, PartitionOffset = k_exfat_fmt_part_lba), the single FAT (bitmap/up-case/root chains), the allocation bitmap with the system clusters pre-marked, the canonical Microsoft up-case table + its checksum, and the root directory entry set. A PC therefore sees a normal partitioned removable disk and the volume mounts with no repair; ra8_fs_mount follows the MBR back to the partition.
| [in] | backend | Block-device backend. |
| [in] | total_sectors | Device capacity in device sectors. |
| [in] | bps | Device sector size in bytes (a power of two, 512..4096, validated by the format entry point). |
| [in] | label | Optional volume label (<= 11 chars), may be NULL. |
| k_ra8_ok | A mountable partitioned exFAT volume was written. |
| k_ra8_err_invalid_size | Partition too small for an exFAT volume. |
| k_ra8_err_not_supported | Below the exFAT minimum plus the 1 MiB partition alignment, past the MBR's 32-bit fields (2 TiB at 512-byte sectors), or system cluster chains exceed FAT sector 0. |
| k_ra8_err_* | Backend write failure. |
backend and backend->write_block are non-NULL. total_sectors is the actual device capacity reported by the backend. Definition at line 798 of file ra8_fs_fat_exfat_fmt.c.
References exfat_geom_t::heap_offset, internal_exfat_fmt_place(), internal_exfat_geometry(), internal_exfat_write_bitmap(), internal_exfat_write_boot(), internal_exfat_write_fat(), internal_exfat_write_mbr(), internal_exfat_write_root(), k_exfat_fmt_first_clus, k_ra8_err_not_supported, k_ra8_ok, exfat_geom_t::part_lba, priv_exfat_write_upcase(), exfat_geom_t::root_cluster, exfat_geom_t::spc, and exfat_geom_t::upcase_cluster.
| ra8_err_t priv_exfat_listdir | ( | const ra8_fs_mount_t * | m, |
| const exfat_dir_t * | dir, | ||
| ra8_fs_listdir_cb_t | cb, | ||
| void * | ctx ) |
Enumerate ONE directory of an exFAT volume.
Walks dir's entry stream; every in-use File entry set yields one callback with the ASCII name (truncated to the local buffer, NUL-terminated), the low attribute byte, and the size. Deleted entries and non-file sets (bitmap, up-case table, label) are skipped. Subdirectories are reported like any other entry set, with k_exfat_attr_directory set in the attribute byte.
| [in] | m | Mounted exFAT volume. |
| [in] | dir | Directory to enumerate (priv_exfat_dir_root for the root). |
| [in] | cb | Callback invoked once per visible entry set. |
| [in] | ctx | Cookie forwarded to the callback. |
| k_ra8_ok | Enumeration completed (EOD or end of run reached). |
| k_ra8_err_* | Backend read failure. |
m, dir and cb are non-NULL; mount is exFAT. dir locates an existing directory on this volume. cb ran once per in-use entry set. Definition at line 819 of file ra8_fs_fat_exfat_mutate.c.
References ra8_fs_dirent_t::attr, k_ra8_ok, ra8_fs_dirent_t::name, priv_exfat_cursor_init(), priv_exfat_dir_next(), and ra8_fs_dirent_t::size_bytes.
Referenced by internal_listdir_locked().
| uint8_t priv_exfat_name_chunk_eq | ( | const uint8_t * | entry, |
| const uint16_t * | name, | ||
| uint32_t | pos, | ||
| uint32_t | nlen ) |
Compare one file-name entry's 15 UTF-16 units against a needle.
Case-insensitive under the canonical up-case table (priv_exfat_upcase_unit), which is the fold the exFAT specification defines name matching against. Positions at/after nlen are treated as already matched (tail padding).
It used to compare the low byte of each unit with an ASCII fold and reject any unit whose high byte was set, so a name outside ASCII never matched at all (#606).
| [in] | entry | 32-byte file-name (0xC1) entry. |
| [in] | name | Target name as UTF-16 code units. |
| [in] | pos | Index of the first name unit this entry covers. |
| [in] | nlen | Total name length in UTF-16 units. |
| 1 | Slice matches. |
| 0 | At least one folded unit differs. |
entry and name are non-NULL. name holds at least nlen units. Definition at line 258 of file ra8_fs_fat_exfat_read.c.
References k_exfat_name_off, k_exfat_name_per_entry, priv_exfat_upcase_unit(), and priv_rd16().
Referenced by internal_exfat_match_set(), and internal_exfat_take_set().
| uint16_t priv_exfat_name_hash | ( | const uint16_t * | name, |
| uint32_t | nlen ) |
Compute the exFAT NameHash for a name in UTF-16 code units.
Hashes the up-cased UTF-16LE name (low then high byte per unit), up-casing through priv_exfat_upcase_unit – the volume's own table, which is what the specification defines the hash over.
Up-casing with an ASCII-only rule, which is what this did, stored a hash no compliant reader recomputes for any name outside ASCII: the host could see the file listed and then fail to find it, because the hash is the index it probes with (#606).
| [in] | name | File name as UTF-16 code units. |
| [in] | nlen | Name length in UTF-16 units. |
| 0..0xFFFF | The hash value. |
name is non-NULL and holds at least nlen units. Definition at line 49 of file ra8_fs_fat_exfat_write.c.
References internal_exfat_csum_add(), k_utf_byte_mask, k_utf_byte_shift, and priv_exfat_upcase_unit().
Referenced by internal_exchk_verify_set(), internal_exfat_build_dir_set(), internal_exfat_build_rename_set(), and internal_exfat_build_set().
| ra8_err_t priv_exfat_name_to_units | ( | const ra8_fs_mount_t * | m, |
| const char * | path, | ||
| uint16_t * | out, | ||
| uint32_t * | out_units ) |
Convert a caller's exFAT name to code units, refusing what will not fold.
The one place an exFAT path becomes the units every on-disk structure counts in. Two refusals, both loud: a name that is not well-formed UTF-8, and a name outside ASCII on a volume whose up-case table this build cannot reproduce – because the NameHash it would store is one the host disagrees with (see priv_exfat_upcase_verify).
| [in] | m | Mounted exFAT volume. |
| [in] | path | Caller's name, NUL-terminated UTF-8, no leading slash. |
| [out] | out | Receives up to k_exfat_name_cap code units. |
| [out] | out_units | Receives the unit count. |
| k_ra8_ok | Converted. |
| k_ra8_err_invalid_arg | path is not well-formed UTF-8. |
| k_ra8_err_no_mem | Over k_exfat_name_cap units. |
| k_ra8_err_not_supported | Non-ASCII on a volume with a foreign table. |
out holds k_exfat_name_cap units. m is a mounted exFAT volume. Definition at line 274 of file ra8_fs_fat_exfat_read.c.
References ra8_fs_mount_t::exfat_upcase_ok, k_exfat_name_cap, k_ra8_err_not_supported, k_ra8_ok, priv_utf16_all_ascii(), and priv_utf8_to_utf16().
Referenced by internal_exfat_enter(), priv_exfat_find(), priv_exfat_mkdir(), priv_exfat_needle_units(), and priv_exfat_open_write().
| ra8_err_t priv_exfat_needle_units | ( | const ra8_fs_mount_t * | m, |
| const char * | name, | ||
| uint16_t * | out, | ||
| uint32_t * | out_units, | ||
| ra8_err_t | too_long ) |
Convert a leaf name to code units, mapping over-long to too_long.
The exact wrapper the mutate verbs share: priv_exfat_name_to_units plus the one line that turns its k_ra8_err_no_mem – a name past the cap – into whatever "absent" or "unsupported" code the caller reports. Factored out so find_set, rename and the create paths do not each restate it (#606).
| [in] | m | Mounted exFAT volume. |
| [in] | name | Leaf name, NUL-terminated UTF-8, no leading slash. |
| [out] | out | Receives up to k_exfat_name_cap code units. |
| [out] | out_units | Receives the unit count. |
| [in] | too_long | The code returned when name exceeds the cap. |
| k_ra8_ok | Converted. |
| too_long | name is longer than k_exfat_name_cap. |
| k_ra8_err_invalid_arg | name is not well-formed UTF-8. |
| k_ra8_err_not_supported | Non-ASCII on a volume with a foreign table. |
out holds k_exfat_name_cap units. m is a mounted exFAT volume. Definition at line 298 of file ra8_fs_fat_exfat_read.c.
References k_ra8_err_no_mem, and priv_exfat_name_to_units().
Referenced by priv_exfat_find_set(), and priv_exfat_rename().
| ra8_err_t priv_exfat_next_entry | ( | const ra8_fs_mount_t * | m, |
| exfat_cursor_t * | cur, | ||
| uint8_t * | out ) |
Fetch the next 32-byte directory entry, following the cluster chain.
Advances across sectors and (via the FAT) clusters. Reports end-of-directory as k_ra8_err_not_found when the chain reaches EOC.
| [in] | m | Mounted exFAT volume. |
| [in,out] | cur | Cursor; advanced by one entry on success. |
| [out] | out | Receives the 32-byte entry. |
| k_ra8_ok | out holds the next entry. |
| k_ra8_err_not_found | The directory chain ended (EOC). |
| k_ra8_err_* | Backend or FAT read failure. |
m, cur, and out are non-NULL. Definition at line 231 of file ra8_fs_fat_exfat_read.c.
References exfat_cursor_t::cluster, exfat_cursor_t::contig_end, exfat_cursor_t::entry_in_cluster, k_exfat_entry_bytes, k_ra8_ok, priv_bps(), priv_byte_copy(), priv_cluster_bytes(), priv_cluster_to_lba(), priv_exfat_step_cluster(), priv_read_sector(), priv_sec_io(), and exfat_cursor_t::scanned.
Referenced by internal_exchk_scan_dir(), internal_exchk_scan_dir_terminal(), internal_exchk_set(), internal_exfat_dir_is_empty(), internal_exfat_dir_relen(), internal_exfat_gather_name(), internal_exfat_gather_set(), internal_exfat_list_emit(), internal_exfat_locate_label(), internal_exfat_match_set(), internal_exfat_take_set(), internal_setattr_exfat(), internal_utime_exfat(), priv_exfat_dir_next(), priv_exfat_drop_set(), priv_exfat_find(), priv_exfat_find_bitmap(), priv_exfat_find_set(), and priv_exfat_upcase_verify().
| ra8_err_t priv_exfat_open | ( | ra8_fs_mount_t * | handle, |
| const char * | path, | ||
| ra8_fs_mode_t | mode, | ||
| ra8_fs_file_t ** | out_file ) |
Open a file (read-only) on a mounted exFAT volume.
Resolves path in the root directory and populates a read handle; write/append modes are rejected (exFAT is read-only here). A name that resolves to a directory is rejected rather than opened as the empty file its zero DataLength would otherwise describe (#604).
| [in] | handle | Mounted exFAT volume. |
| [in] | path | Flat root-level file name, UTF-8. |
| [in] | mode | Open mode; only k_ra8_fs_mode_read is supported. |
| [out] | out_file | Receives the open handle. |
| k_ra8_ok | File opened. |
| k_ra8_err_not_supported | Write/append requested (exFAT is read-only). |
| k_ra8_err_invalid_arg | path names a directory, not a file. |
| k_ra8_err_not_found | No such file. |
| k_ra8_err_no_mem | File table full. |
handle, path, out_file are non-NULL; mount is exFAT. handle is in use. Definition at line 474 of file ra8_fs_fat_exfat_read.c.
References internal_exfat_seed_read(), k_exfat_attr_directory, k_exfat_entry_bytes, k_ra8_err_invalid_arg, k_ra8_err_no_mem, k_ra8_fs_mode_read, k_ra8_ok, priv_alloc_file_slot(), priv_exfat_lookup(), and priv_exfat_open_write().
Referenced by priv_open_locked().
| ra8_err_t priv_exfat_rename | ( | const ra8_fs_mount_t * | m, |
| const char * | old_path, | ||
| const char * | new_path ) |
Rename a root-level file on an exFAT volume, at any storable length.
Rewrites the whole entry set under the new name: the Stream entry's NameLength + NameHash, a run of one Name entry per fifteen UTF-16 units, the File entry's SecondaryCount, and the recomputed SetChecksum. When the new name keeps the entry count the set is rewritten in place; when it needs more or fewer Name entries the set is relocated to a fresh run of slots (growing the directory if needed) and the old set is then retired, so names up to k_exfat_name_cap units – the same range ra8_fs_write_file() writes – all rename. The data itself never moves: FirstCluster, DataLength and the timestamps ride across untouched.
| [in] | m | Mounted exFAT volume. |
| [in] | old_path | Existing root-level name. |
| [in] | new_path | Replacement name (must not exist). |
| k_ra8_ok | File renamed. |
| k_ra8_err_not_found | old_path does not exist. |
| k_ra8_err_exists | new_path already resolves. |
| k_ra8_err_invalid_arg | new_path is empty, over the name cap, or not well-formed UTF-8. |
| k_ra8_err_not_supported | The paths cross directories, or a non-ASCII name on a volume with a foreign up-case table. |
| k_ra8_err_no_mem | The directory cannot grow to hold a longer set. |
m and both paths are non-NULL; mount is exFAT. new_path resolves to the same data; old_path is gone. Definition at line 593 of file ra8_fs_fat_exfat_mutate.c.
References internal_exfat_build_rename_set(), internal_exfat_place_rename(), internal_exfat_rename_prepare(), k_exfat_attr_read_only, k_exfat_entry_bytes, k_exfat_max_set_bytes, k_exfat_name_cap, k_exfat_off_file_attr, k_exfat_set_max_entries, k_ra8_err_access_denied, k_ra8_err_exists, k_ra8_err_invalid_arg, k_ra8_ok, priv_exfat_find(), priv_exfat_find_set(), and priv_exfat_needle_units().
| uint16_t priv_exfat_set_checksum | ( | const uint8_t * | set, |
| uint32_t | bytes ) |
Compute the SetChecksum over a built directory entry set.
Folds every byte except the File entry's checksum field (bytes 2-3).
| [in] | set | Contiguous entry-set bytes (File + Stream + Name entries). |
| [in] | bytes | Total byte count of the set. |
| 0..0xFFFF | The checksum. |
set is non-NULL and at least bytes long. bytes is a multiple of the entry size. set is unmodified. Definition at line 65 of file ra8_fs_fat_exfat_write.c.
References internal_exfat_csum_add(), and k_exfat_off_file_csum.
Referenced by internal_exchk_verify_set(), internal_exfat_build_dir_set(), internal_exfat_build_rename_set(), internal_exfat_build_set(), internal_exfat_dir_relen(), internal_setattr_exfat(), internal_utime_exfat(), and priv_exfat_flush_set().
| ra8_err_t priv_exfat_unlink | ( | const ra8_fs_mount_t * | m, |
| const char * | path ) |
Delete a file on an exFAT volume, at any depth.
Resolves the path's parent, then hands the leaf to priv_exfat_unlink_at: the entry set is located, every entry's in-use bit (bit 7 of the entry type) is cleared, and the clusters are freed in the allocation bitmap. A set carrying k_exfat_attr_directory is refused: freeing a directory's run would strand every entry inside it (#604).
| [in] | m | Mounted exFAT volume. |
| [in] | path | File path, UTF-8, nested or root-level. |
| k_ra8_ok | File unlinked. |
| k_ra8_err_invalid_arg | path names a directory or the volume root. |
| k_ra8_err_not_found | No such file, or a component is missing. |
| k_ra8_err_* | Directory or bitmap write failure. |
m and path are non-NULL; mount is exFAT. Definition at line 383 of file ra8_fs_fat_exfat_mutate.c.
References k_ra8_err_invalid_arg, k_ra8_ok, priv_exfat_resolve_parent(), priv_exfat_unlink_at(), and priv_strlen().
| uint32_t priv_exfat_upcase_checksum | ( | void | ) |
Rotate-add checksum of the up-case table this build embeds.
The same 32-bit fold priv_exfat_write_upcase records in the volume's up-case directory entry, computed over the in-flash table. Having it as a function rather than a constant is the point: a constant could drift from the bytes it claims to describe, and this cannot.
| 0xE619D30D | The canonical Microsoft table, which is what is embedded. |
Definition at line 471 of file ra8_fs_fat_exfat_upcase.c.
References k_exfat_fmt_upc_std_bytes, priv_exfat_csum32(), and s_exfat_upcase.
Referenced by priv_exfat_upcase_verify().
| uint16_t priv_exfat_upcase_unit | ( | uint16_t | unit | ) |
Fold a UTF-16 code unit through the canonical exFAT up-case table.
The exFAT specification defines both NameHash and name comparison over the UP-CASED name, using the table the volume carries. This build embeds and writes the canonical Microsoft table – the one mkfs.exfat and the Windows formatter emit, checksum 0xE619D30D – and this is the reader for it, so the hash stored on create is the hash a host recomputes.
Look-up walks the compressed table rather than expanding it, because the expansion is 128 KiB. The ASCII range short-circuits to priv_ascii_upper, which the table agrees with for every one of those 128 units.
A surrogate unit folds to itself: the table covers the BMP, and a supplementary code point has no simple case mapping inside a single unit.
| [in] | unit | UTF-16 code unit to fold. |
| unit | No mapping applies (identity run, or past the table). |
| other | The table's mapping for unit. |
unit and the embedded table. Definition at line 435 of file ra8_fs_fat_exfat_upcase.c.
References k_exfat_upc_run_tag, k_exfat_upc_words, k_utf_ascii_max, priv_ascii_upper(), priv_rd16(), and s_exfat_upcase.
Referenced by priv_exfat_name_chunk_eq(), priv_exfat_name_hash(), and priv_utf16_ieq().
| void priv_exfat_upcase_verify | ( | ra8_fs_mount_t * | m | ) |
Decide whether this build's fold matches the mounted volume's table.
Walks the root directory for the up-case-table entry (0x82) and compares its TableChecksum against priv_exfat_upcase_checksum(). The answer lands in ra8_fs_mount_t::exfat_upcase_ok and decides one thing: whether a name containing anything outside ASCII may be created, renamed or looked up on this volume at all. An ASCII-only name folds identically under every conforming table, so it is never affected.
Refusing the operation is the point. Hashing a name with a fold the volume does not use stores a NameHash the host disagrees with, and a host that cannot match the hash cannot find a file it can see listed – a disagreement with the on-disk format rather than a limitation of this API (#606).
A missing entry or a read error is treated exactly like a mismatch, so a volume this function could not interrogate degrades to ASCII-only names rather than failing to mount.
| [in,out] | m | Mount whose exFAT geometry is already populated. |
m is non-NULL and its exFAT region geometry is valid. Definition at line 133 of file ra8_fs_fat_exfat_read.c.
References ra8_fs_mount_t::exfat_upcase_ok, k_exfat_entry_bytes, k_exfat_entry_eod, k_exfat_entry_upcase, k_exfat_scan_limit, k_exfat_upc_off_csum, k_ra8_ok, priv_exfat_next_entry(), priv_exfat_upcase_checksum(), priv_rd32(), ra8_fs_mount_t::root_cluster, and exfat_cursor_t::scanned.
Referenced by internal_exfat_parse().