1 /* read and write binary file "partitions" described by FMAP */ 2 /* SPDX-License-Identifier: GPL-2.0-only */ 3 4 #ifndef PARITITONED_FILE_H_ 5 #define PARITITONED_FILE_H_ 6 7 #include "common.h" 8 #include "flashmap/fmap.h" 9 10 #include <stdbool.h> 11 #include <stddef.h> 12 13 typedef struct partitioned_file partitioned_file_t; 14 15 /** 16 * Create a new filesystem-backed flat buffer. 17 * This backwards-compatibility function creates a new in-memory buffer and 18 * backing binary file of the specified size. Although the file won't actually 19 * have multiple regions, it'll still be possible to access and manipulate it 20 * using this module; this is accomplished by requesting the special region 21 * whose name matches SECTION_NAME_PRIMARY_CBFS, which maps to the whole file. 22 * Note that the caller will be responsible for calling partitioned_file_close() 23 * on the returned object, and that this function will overwrite any existing 24 * file with the given name without warning. 25 * 26 * @param filename Name of the backing file 27 * @param image_size Size of the image 28 * @return Caller-owned partitioned file, or NULL on error 29 */ 30 partitioned_file_t *partitioned_file_create_flat(const char *filename, 31 size_t image_size); 32 33 /** 34 * Create a new filesystem-backed partitioned buffer. 35 * This creates a new in-memory buffer and backing binary file. Both are 36 * segmented into regions according to the provided flashmap's sections, and the 37 * flashmap itself is automatically copied into the region named 38 * SECTION_NAME_FMAP: a section with this name must already exist in the FMAP. 39 * After calling this function, it is safe for the caller to clean up flashmap 40 * at any time. The partitioned_file_t returned from this function is separately 41 * owned by the caller, and must later be passed to partitioned_file_close(). 42 * Note that this function will overwrite any existing file with the given name 43 * without warning. 44 * 45 * @param filename Name of the backing file 46 * @param flashmap Buffer containing an FMAP file layout 47 * @return Caller-owned partitioned file, or NULL on error 48 */ 49 partitioned_file_t *partitioned_file_create(const char *filename, 50 struct buffer *flashmap); 51 52 /** 53 * Read a file back in from the disk. 54 * An in-memory buffer is created and populated with the file's 55 * contents. If the image contains an FMAP, it will be opened as a 56 * full partitioned file; otherwise, it will be opened as a flat file as 57 * if it had been created by partitioned_file_create_flat(). 58 * The partitioned_file_t returned from this function is separately owned by the 59 * caller, and must later be passed to partitioned_file_close(); 60 * 61 * @param filename Name of the file to read in 62 * @param write_access True if the file needs to be modified 63 * @return Caller-owned partitioned file, or NULL on error 64 */ 65 partitioned_file_t *partitioned_file_reopen(const char *filename, 66 bool write_access); 67 68 /** 69 * Write a buffer's contents to its original region within a segmented file. 70 * This function should only be called on buffers originally retrieved by a call 71 * to partitioned_file_read_region() on the same partitioned file object. The 72 * contents of this buffer are copied back to the same region of the buffer and 73 * backing file that the region occupied before. 74 * 75 * @param file Partitioned file to which to write the data 76 * @param buffer Modified buffer obtained from partitioned_file_read_region() 77 * @return Whether the operation was successful 78 */ 79 bool partitioned_file_write_region(partitioned_file_t *file, 80 const struct buffer *buffer); 81 82 /** 83 * Obtain one particular region of a segmented file. 84 * The result is owned by the partitioned_file_t and shared among every caller 85 * of this function. Thus, it is an error to buffer_delete() it; instead, clean 86 * up the entire partitioned_file_t once it's no longer needed with a single 87 * call to partitioned_file_close(). 88 * Note that, if the buffer obtained from this function is modified, the changes 89 * will be reflected in any buffers handed out---whether earlier or later---for 90 * any region inclusive of the altered location(s). However, the backing file 91 * will not be updated until someone calls partitioned_file_write_region() on a 92 * buffer that includes the alterations. 93 * 94 * @param dest Empty destination buffer for the data 95 * @param file Partitioned file from which to read the data 96 * @param region Name of the desired FMAP region 97 * @return Whether the copy was performed successfully 98 */ 99 bool partitioned_file_read_region(struct buffer *dest, 100 const partitioned_file_t *file, const char *region); 101 102 /** @param file Partitioned file to flush and cleanup */ 103 void partitioned_file_close(partitioned_file_t *file); 104 105 /** @return Whether the file is partitioned (i.e. not flat). */ 106 bool partitioned_file_is_partitioned(const partitioned_file_t *file); 107 108 /** @return The image's overall filesize, regardless of whether it's flat. */ 109 size_t partitioned_file_total_size(const partitioned_file_t *file); 110 111 /** @return Whether the specified region begins with the magic bytes. */ 112 bool partitioned_file_region_check_magic(const partitioned_file_t *file, 113 const char *region, const char *magic, size_t magic_len); 114 115 /** @return Whether the specified region exists and contains nested regions. */ 116 bool partitioned_file_region_contains_nested(const partitioned_file_t *file, 117 const char *region); 118 119 /** @return An immutable reference to the FMAP, or NULL for flat images. */ 120 const struct fmap *partitioned_file_get_fmap(const partitioned_file_t *file); 121 122 /** @return Whether to include area in the running count. */ 123 typedef bool (*partitioned_file_fmap_selector_t) 124 (const struct fmap_area *area, const void *arg); 125 126 /** 127 * Count the number of FMAP entries fulfilling a certain criterion. 128 * The result is always 0 if run on a flat (non-partitioned) image. 129 * 130 * @param file File on whose FMAP entries the operation should be run 131 * @param callback Decider answering whether each individual region should count 132 * @param arg Additional information to furnish to the decider on each call 133 * @return The number of FMAP sections with that property 134 */ 135 unsigned partitioned_file_fmap_count(const partitioned_file_t *file, 136 partitioned_file_fmap_selector_t callback, const void *arg); 137 138 /** Selector that counts every single FMAP section. */ 139 extern const partitioned_file_fmap_selector_t partitioned_file_fmap_select_all; 140 141 /** Selector that counts FMAP sections that are descendants of fmap_area arg. */ 142 extern const partitioned_file_fmap_selector_t 143 partitioned_file_fmap_select_children_of; 144 145 /** Selector that counts FMAP sections that contain the fmap_area arg. */ 146 extern const partitioned_file_fmap_selector_t 147 partitioned_file_fmap_select_parents_of; 148 149 #endif 150