summaryrefslogtreecommitdiffstatshomepage
path: root/src/tools/imgtool/modules/fat.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/imgtool/modules/fat.cpp')
-rw-r--r--src/tools/imgtool/modules/fat.cpp177
1 files changed, 96 insertions, 81 deletions
diff --git a/src/tools/imgtool/modules/fat.cpp b/src/tools/imgtool/modules/fat.cpp
index 029050d1e9c..d6611932c0d 100644
--- a/src/tools/imgtool/modules/fat.cpp
+++ b/src/tools/imgtool/modules/fat.cpp
@@ -134,13 +134,17 @@
****************************************************************************/
-#include <time.h>
-#include <ctype.h>
-#include "imgtool.h"
-#include "formats/imageutl.h"
-#include "unicode.h"
#include "fat.h"
+#include "corestr.h"
+#include "multibyte.h"
+#include "unicode.h"
+
+#include <algorithm>
+#include <cctype>
+#include <cstdio>
+#include <ctime>
+
#define FAT_DIRENT_SIZE 32
#define FAT_SECLEN 512
@@ -176,6 +180,18 @@ struct fat_file
struct fat_dirent
{
+ fat_dirent() :
+ directory(0),
+ eof(0),
+ filesize(0),
+ first_cluster(0),
+ dirent_sector_index(0),
+ dirent_sector_offset(0)
+ {
+ std::fill(std::begin(long_filename), std::end(long_filename), 0);
+ std::fill(std::begin(short_filename), std::end(short_filename), 0);
+ }
+
char long_filename[512];
char short_filename[13];
unsigned int directory : 1;
@@ -364,14 +380,12 @@ static imgtoolerr_t fat_write_sector(imgtool::partition &partition, uint32_t sec
}
-#ifdef UNUSED_FUNCTION
-static imgtoolerr_t fat_clear_sector(imgtool::partition &partition, uint32_t sector_index, uint8_t data)
+[[maybe_unused]] static imgtoolerr_t fat_clear_sector(imgtool::partition &partition, uint32_t sector_index, uint8_t data)
{
char buf[FAT_SECLEN];
memset(buf, data, sizeof(buf));
return fat_write_sector(partition, sector_index, 0, buf, sizeof(buf));
}
-#endif
static imgtoolerr_t fat_partition_open(imgtool::partition &partition, uint64_t first_block, uint64_t block_count)
@@ -410,19 +424,19 @@ static imgtoolerr_t fat_partition_open(imgtool::partition &partition, uint64_t f
}
info->fat_bits = fat_bits;
- sector_size = pick_integer_le(header, 11, 2);
- info->sectors_per_cluster = pick_integer_le(header, 13, 1);
- info->reserved_sectors = pick_integer_le(header, 14, 2);
- info->fat_count = pick_integer_le(header, 16, 1);
- info->root_entries = pick_integer_le(header, 17, 2);
- total_sectors_l = pick_integer_le(header, 19, 2);
- info->sectors_per_fat = pick_integer_le(header, 22, 2);
- total_sectors_h = pick_integer_le(header, 32, 4);
+ sector_size = get_u16le(&header[11]);
+ info->sectors_per_cluster = header[13];
+ info->reserved_sectors = get_u16le(&header[14]);
+ info->fat_count = header[16];
+ info->root_entries = get_u16le(&header[17]);
+ total_sectors_l = get_u16le(&header[19]);
+ info->sectors_per_fat = get_u16le(&header[22]);
+ total_sectors_h = get_u32le(&header[32]);
if (info->sectors_per_cluster == 0)
return IMGTOOLERR_CORRUPTIMAGE;
- info->total_sectors = total_sectors_l + (((uint64_t) total_sectors_h) << 16);
+ info->total_sectors = total_sectors_l + (uint64_t(total_sectors_h) << 16);
available_sectors = info->total_sectors - info->reserved_sectors
- (info->sectors_per_fat * info->fat_count)
- (info->root_entries * FAT_DIRENT_SIZE + FAT_SECLEN - 1) / FAT_SECLEN;
@@ -520,24 +534,24 @@ static imgtoolerr_t fat_partition_create(imgtool::image &image, uint64_t first_b
/* prepare the header */
memset(header, 0, sizeof(header));
memcpy(&header[3], "IMGTOOL ", 8);
- place_integer_le(header, 11, 2, FAT_SECLEN);
- place_integer_le(header, 13, 1, sectors_per_cluster);
- place_integer_le(header, 14, 1, reserved_sectors);
- place_integer_le(header, 16, 1, fat_count);
- place_integer_le(header, 17, 2, root_dir_count);
- place_integer_le(header, 19, 2, (uint16_t) (block_count >> 0));
- place_integer_le(header, 21, 1, media_descriptor);
- place_integer_le(header, 22, 2, sectors_per_fat);
- place_integer_le(header, 24, 2, sectors_per_track);
- place_integer_le(header, 26, 2, heads);
- place_integer_le(header, 28, 4, hidden_sectors);
- place_integer_le(header, 32, 4, (uint32_t) (block_count >> 16));
- place_integer_le(header, 36, 1, 0xFF);
- place_integer_le(header, 38, 1, 0x28);
- place_integer_le(header, 39, 1, std::rand());
- place_integer_le(header, 40, 1, std::rand());
- place_integer_le(header, 41, 1, std::rand());
- place_integer_le(header, 42, 1, std::rand());
+ put_u16le(&header[11], FAT_SECLEN);
+ header[13] = sectors_per_cluster;
+ header[14] = reserved_sectors;
+ header[16] = fat_count;
+ put_u16le(&header[17], root_dir_count);
+ put_u16le(&header[19], uint16_t(block_count >> 0));
+ header[21] = media_descriptor;
+ put_u16le(&header[22], sectors_per_fat);
+ put_u16le(&header[24], sectors_per_track);
+ put_u16le(&header[26], heads);
+ put_u32le(&header[28], hidden_sectors);
+ put_u32le(&header[32], uint32_t(block_count >> 16));
+ header[36] = 0xFF;
+ header[38] = 0x28;
+ header[39] = std::rand();
+ header[40] = std::rand();
+ header[41] = std::rand();
+ header[42] = std::rand();
memcpy(&header[43], " ", 11);
memcpy(&header[54], fat_bits_string, 8);
@@ -553,14 +567,14 @@ static imgtoolerr_t fat_partition_create(imgtool::image &image, uint64_t first_b
if (boot_sector_offset <= 129)
{
header[0] = 0xEB; /* JMP rel8 */
- header[1] = (uint8_t) (boot_sector_offset - 2); /* (offset) */
+ header[1] = uint8_t(boot_sector_offset - 2); /* (offset) */
header[2] = 0x90; /* NOP */
}
else
{
header[0] = 0xE9; /* JMP rel16 */
- header[1] = (uint8_t) ((boot_sector_offset - 2) >> 0); /* (offset) */
- header[2] = (uint8_t) ((boot_sector_offset - 2) >> 8); /* (offset) */
+ header[1] = uint8_t((boot_sector_offset - 2) >> 0); /* (offset) */
+ header[2] = uint8_t((boot_sector_offset - 2) >> 8); /* (offset) */
}
err = image.write_block(first_block, header);
@@ -578,9 +592,9 @@ static imgtoolerr_t fat_partition_create(imgtool::image &image, uint64_t first_b
// FIXME: this causes a corrupt PC floppy image since it doubles the FAT partition header - works without it though
#if 0
/* set first two FAT entries */
- first_fat_entries = ((uint64_t) media_descriptor) | 0xFFFFFF00;
- first_fat_entries &= (((uint64_t) 1) << fat_bits) - 1;
- first_fat_entries |= ((((uint64_t) 1) << fat_bits) - 1) << fat_bits;
+ first_fat_entries = uint64_t(media_descriptor) | 0xFFFFFF00;
+ first_fat_entries &= (uint64_t(1) << fat_bits) - 1;
+ first_fat_entries |= ((uint64_t(1) << fat_bits) - 1) << fat_bits;
first_fat_entries = little_endianize_int64(first_fat_entries);
for (i = 0; i < fat_count; i++)
@@ -706,8 +720,8 @@ static uint32_t fat_get_fat_entry(imgtool::partition &partition, const uint8_t *
entry &= bit_mask;
if (i == 0)
- last_entry = (uint32_t) entry;
- else if (last_entry != (uint32_t) entry)
+ last_entry = uint32_t(entry);
+ else if (last_entry != uint32_t(entry))
return 1; /* if the FATs disagree; mark this as reserved */
}
@@ -739,8 +753,8 @@ static void fat_set_fat_entry(imgtool::partition &partition, uint8_t *fat_table,
* disk_info->sectors_per_fat) + (bit_index / 8), sizeof(entry));
entry = little_endianize_int64(entry);
- entry &= (~((uint64_t) 0xFFFFFFFF >> (32 - disk_info->fat_bits)) << (bit_index % 8)) | ((1 << (bit_index % 8)) - 1);
- entry |= ((uint64_t) value) << (bit_index % 8);
+ entry &= (~(uint64_t(0xFFFFFFFF) >> (32 - disk_info->fat_bits)) << (bit_index % 8)) | ((1 << (bit_index % 8)) - 1);
+ entry |= uint64_t(value) << (bit_index % 8);
entry = little_endianize_int64(entry);
memcpy(fat_table + (i * FAT_SECLEN
@@ -1080,8 +1094,8 @@ static imgtoolerr_t fat_set_file_size(imgtool::partition &partition, fat_file *f
}
/* record the new file size */
- place_integer_le(dirent, 26, 2, file->first_cluster);
- place_integer_le(dirent, 28, 4, new_size);
+ put_u16le(&dirent[26], file->first_cluster);
+ put_u32le(&dirent[28], new_size);
/* delete the file, if appropriate */
if (delete_file)
@@ -1228,7 +1242,7 @@ static void fat_canonicalize_sfn(char *sfn, const uint8_t *sfn_bytes)
memcpy(sfn, sfn_bytes, 8);
rtrim(sfn);
if (sfn[0] == 0x05)
- sfn[0] = (char) 0xE5;
+ sfn[0] = char(0xE5);
if ((sfn_bytes[8] != ' ') || (sfn_bytes[9] != ' ') || (sfn_bytes[10] != ' '))
{
strcat(sfn, ".");
@@ -1272,15 +1286,16 @@ static uint32_t fat_setup_time(time_t ansi_time)
-static imgtoolerr_t fat_read_dirent(imgtool::partition &partition, fat_file *file,
- fat_dirent &ent, fat_freeentry_info *freeent)
+static imgtoolerr_t fat_read_dirent(
+ imgtool::partition &partition,
+ fat_file *file,
+ fat_dirent &ent,
+ fat_freeentry_info *freeent)
{
imgtoolerr_t err;
//const fat_partition_info *disk_info;
uint8_t entry[FAT_DIRENT_SIZE];
size_t bytes_read;
- int i, j;
- char32_t ch;
char16_t lfn_buf[512];
size_t lfn_len = 0;
int lfn_lastentry = 0;
@@ -1289,7 +1304,7 @@ static imgtoolerr_t fat_read_dirent(imgtool::partition &partition, fat_file *fil
assert(file->directory);
lfn_buf[0] = '\0';
- memset(&ent, 0, sizeof(ent));
+ ent = fat_dirent();
//disk_info = fat_get_partition_info(partition);
/* The first eight bytes of a FAT directory entry is a blank padded name
@@ -1326,11 +1341,11 @@ static imgtoolerr_t fat_read_dirent(imgtool::partition &partition, fat_file *fil
lfn_checksum = entry[13];
}
lfn_lastentry = entry[0] & 0x3F;
- prepend_lfn_bytes(lfn_buf, ARRAY_LENGTH(lfn_buf),
+ prepend_lfn_bytes(lfn_buf, std::size(lfn_buf),
&lfn_len, entry, 28, 2);
- prepend_lfn_bytes(lfn_buf, ARRAY_LENGTH(lfn_buf),
+ prepend_lfn_bytes(lfn_buf, std::size(lfn_buf),
&lfn_len, entry, 14, 6);
- prepend_lfn_bytes(lfn_buf, ARRAY_LENGTH(lfn_buf),
+ prepend_lfn_bytes(lfn_buf, std::size(lfn_buf),
&lfn_len, entry, 1, 5);
}
else if (freeent && (freeent->position == ~0))
@@ -1350,7 +1365,7 @@ static imgtoolerr_t fat_read_dirent(imgtool::partition &partition, fat_file *fil
}
}
}
- while((entry[0] == 0x2E) || (entry[0] == 0xE5) || (entry[11] == 0x0F));
+ while ((entry[0] == 0x2E) || (entry[0] == 0xE5) || (entry[11] == 0x0F));
/* no more directory entries? */
if (entry[0] == '\0')
@@ -1368,25 +1383,25 @@ static imgtoolerr_t fat_read_dirent(imgtool::partition &partition, fat_file *fil
/* only use the LFN if the checksum passes */
if (lfn_checksum == fat_calc_filename_checksum(entry))
{
- i = 0;
- j = 0;
+ int i = 0, j = 0;
+ char32_t ch;
do
{
- i += uchar_from_utf16(&ch, &lfn_buf[i], ARRAY_LENGTH(lfn_buf) - i);
- j += utf8_from_uchar(&ent.long_filename[j], ARRAY_LENGTH(ent.long_filename) - j, ch);
+ i += uchar_from_utf16(&ch, &lfn_buf[i], std::size(lfn_buf) - i);
+ j += utf8_from_uchar(&ent.long_filename[j], std::size(ent.long_filename) - j, ch);
}
- while(ch != 0);
+ while (ch != 0);
}
}
/* other attributes */
- ent.filesize = pick_integer_le(entry, 28, 4);
+ ent.filesize = get_u32le(&entry[28]);
ent.directory = (entry[11] & 0x10) ? 1 : 0;
- ent.first_cluster = pick_integer_le(entry, 26, 2);
+ ent.first_cluster = get_u16le(&entry[26]);
ent.dirent_sector_index = entry_sector_index;
ent.dirent_sector_offset = entry_sector_offset;
- ent.creation_time = fat_crack_time(pick_integer_le(entry, 14, 4));
- ent.lastmodified_time = fat_crack_time(pick_integer_le(entry, 22, 4));
+ ent.creation_time = fat_crack_time(get_u32le(&entry[14]));
+ ent.lastmodified_time = fat_crack_time(get_u32le(&entry[22]));
return IMGTOOLERR_SUCCESS;
}
@@ -1440,9 +1455,9 @@ static imgtoolerr_t fat_construct_dirent(const char *filename, creation_policy_t
/* set up file dates in the new dirent */
now = fat_setup_time(time(NULL));
- place_integer_le(created_entry, 14, 4, now);
- place_integer_le(created_entry, 18, 2, now);
- place_integer_le(created_entry, 22, 4, now);
+ put_u32le(&created_entry[14], now);
+ put_u16le(&created_entry[18], now);
+ put_u32le(&created_entry[22], now);
while(*filename)
{
@@ -1451,13 +1466,13 @@ static imgtoolerr_t fat_construct_dirent(const char *filename, creation_policy_t
/* append to short filename, if possible */
if ((ch < 32) || (ch > 128))
short_char = '\0';
- else if (isalnum((char) ch))
- short_char = toupper((char) ch);
- else if (strchr(".!#$%^()-@^_`{}~", (char) ch))
- short_char = (char) ch;
+ else if (isalnum(char(ch)))
+ short_char = toupper(char(ch));
+ else if (strchr(".!#$%^()-@^_`{}~", char(ch)))
+ short_char = char(ch);
else
short_char = '\0'; /* illegal SFN char */
- canonical_short_char = fat_canonicalize_sfn_char((char) ch);
+ canonical_short_char = fat_canonicalize_sfn_char(char(ch));
if (!short_char || (short_char != canonical_short_char))
{
if (toupper(short_char) == toupper(canonical_short_char))
@@ -1605,7 +1620,7 @@ static void fat_bump_dirent(imgtool::partition &partition, uint8_t *entry, size_
sfn_entry = &entry[entry_len - FAT_DIRENT_SIZE];
digit_place = 1;
- for (pos = 7; (pos >= 0) && isdigit((char) sfn_entry[pos]); pos--)
+ for (pos = 7; (pos >= 0) && isdigit(char(sfn_entry[pos])); pos--)
{
val += (sfn_entry[pos] - '0') * digit_place;
digit_place *= 10;
@@ -1834,7 +1849,7 @@ static imgtoolerr_t fat_partition_nextenum(imgtool::directory &enumeration, imgt
return err;
/* copy stuff from the FAT dirent to the Imgtool dirent */
- snprintf(ent.filename, ARRAY_LENGTH(ent.filename), "%s", fatent.long_filename[0]
+ snprintf(ent.filename, std::size(ent.filename), "%s", fatent.long_filename[0]
? fatent.long_filename : fatent.short_filename);
ent.filesize = fatent.filesize;
ent.directory = fatent.directory;
@@ -1945,7 +1960,7 @@ static imgtoolerr_t fat_partition_writefile(imgtool::partition &partition, const
if (file.directory)
return IMGTOOLERR_FILENOTFOUND;
- bytes_left = (uint32_t) sourcef.size();
+ bytes_left = uint32_t(sourcef.size());
err = fat_set_file_size(partition, &file, bytes_left);
if (err)
@@ -2051,11 +2066,11 @@ static imgtoolerr_t fat_partition_createdir(imgtool::partition &partition, const
/* set up the two directory entries in all directories */
memset(initial_data, 0, sizeof(initial_data));
memcpy(&initial_data[0], ". ", 11);
- place_integer_le(initial_data, 11, 1, 0x10);
- place_integer_le(initial_data, 26, 2, file.first_cluster);
+ initial_data[11] = 0x10;
+ put_u16le(&initial_data[26], file.first_cluster);
memcpy(&initial_data[32], ". ", 11);
- place_integer_le(initial_data, 43, 1, 0x10);
- place_integer_le(initial_data, 58, 2, file.parent_first_cluster);
+ initial_data[43] = 0x10;
+ put_u16le(&initial_data[58], file.parent_first_cluster);
err = fat_write_file(partition, &file, initial_data, sizeof(initial_data), NULL);
if (err)