36#define ROUND_TO_MULTIPLE(n,m) ((n) && (m) ? (n)+(m)-1-((n)-1)%(m) : 0)
40#define FAT12_THRESHOLD 4085
41#define FAT16_THRESHOLD 65525
48 0xf0,
"5.25\" or 3.5\" HD floppy"}, {
50 0xf9,
"3,5\" 720k floppy 2s/80tr/9sec or "
51 "5.25\" 1.2M floppy 2s/80tr/15sec"}, {
52 0xfa,
"5.25\" 320k floppy 1s/80tr/8sec"}, {
53 0xfb,
"3.5\" 640k floppy 2s/80tr/8sec"}, {
54 0xfc,
"5.25\" 180k floppy 1s/40tr/9sec"}, {
55 0xfd,
"5.25\" 360k floppy 2s/40tr/9sec"}, {
56 0xfe,
"5.25\" 160k floppy 1s/40tr/8sec"}, {
570xff,
"5.25\" 320k floppy 2s/40tr/8sec"},};
60#define GET_UNALIGNED_W(f) \
61 ( (uint16_t)f[0] | ((uint16_t)f[1]<<8) )
78 printf(
"Boot sector contents:\n");
81 strncpy(
id, (
const char *)
b->system_id, 8);
83 printf(
"System ID \"%s\"\n",
id);
87 printf(
"Serial number 0x%x\n",
88 b->system_id[5] | (
b->system_id[6] << 8) | (
b->
93 printf(
"%10d bytes per cluster\n",
fs->cluster_size);
94 printf(
"%10d reserved sector%s\n", le16toh(
b->reserved),
95 le16toh(
b->reserved) == 1 ?
"" :
"s");
96 printf(
"First FAT starts at byte %llu (sector %llu)\n",
97 (
unsigned long long)
fs->fat_start,
98 (
unsigned long long)
fs->fat_start / lss);
99 printf(
"%10d FATs, %d bit entries\n",
b->fats,
fs->fat_bits);
100 printf(
"%10lld bytes per FAT (= %llu sectors)\n", (
long long)
fs->fat_size,
101 (
long long)
fs->fat_size / lss);
102 if (!
fs->root_cluster) {
103 printf(
"Root directory starts at byte %llu (sector %llu)\n",
104 (
unsigned long long)
fs->root_start,
105 (
unsigned long long)
fs->root_start / lss);
106 printf(
"%10d root directory entries\n",
fs->root_entries);
108 printf(
"Root directory start at cluster %lu (arbitrary size)\n",
109 (
unsigned long)
fs->root_cluster);
111 printf(
"Data area starts at byte %llu (sector %llu)\n",
112 (
unsigned long long)
fs->data_start,
113 (
unsigned long long)
fs->data_start / lss);
114 printf(
"%10lu data clusters (%llu bytes)\n",
115 (
unsigned long)
fs->data_clusters,
116 (
unsigned long long)
fs->data_clusters *
fs->cluster_size);
117 printf(
"%u sectors/track, %u heads\n", le16toh(
b->secs_track),
121 (((
unsigned char *)&
b->hidden)[0] |
122 ((
unsigned char *)&
b->hidden)[1] << 8) : le32toh(
b->hidden));
131 if (!
fs->backupboot_start) {
132 printf(
"There is no backup boot sector.\n");
133 if (le16toh(
b->reserved) < 3) {
134 printf(
"And there is no space for creating one!\n");
138 printf(
"1) Create one\n2) Do without a backup\n");
140 printf(
" Auto-creating backup boot block.\n");
145 if (le16toh(
b->reserved) >= 7 && le16toh(
b->info_sector) != 6)
148 bbs = le16toh(
b->reserved) - 1;
149 if (bbs == le16toh(
b->info_sector))
152 fs->backupboot_start = bbs * lss;
156 sizeof(
b->backup_boot), &
b->backup_boot);
157 printf(
"Created backup of boot sector in sector %d\n", bbs);
170 printf(
"There are differences between boot sector and its backup.\n");
171 printf(
"This is mostly harmless. Differences: (offset:original/backup)\n ");
192 printf(
"1) Copy original to backup\n"
193 "2) Copy backup to original\n" "3) No action\n");
195 printf(
" Not automatically fixing this.\n");
223 if (!
b->info_sector) {
224 printf(
"No FSINFO sector\n");
226 printf(
"1) Create one\n2) Do without FSINFO\n");
228 printf(
" Not automatically creating it.\n");
233 for (
s = 1;
s < le16toh(
b->reserved); ++
s)
234 if (
s != le16toh(
b->backup_boot))
236 if (
s > 0 &&
s < le16toh(
b->reserved)) {
241 sizeof(
b->info_sector), &
b->info_sector);
242 if (
fs->backupboot_start)
245 sizeof(
b->info_sector), &
b->info_sector);
247 printf(
"No free reserved sector found -- "
248 "no space for FSINFO sector!\n");
255 fs->fsinfo_start = le16toh(
b->info_sector) * lss;
258 if (
i.magic !=
htole32(0x41615252) ||
260 printf(
"FSINFO sector has bad magic number(s):\n");
262 printf(
" Offset %llu: 0x%08x != expected 0x%08x\n",
264 le32toh(
i.magic), 0x41615252);
265 if (
i.signature !=
htole32(0x61417272))
266 printf(
" Offset %llu: 0x%08x != expected 0x%08x\n",
268 le32toh(
i.signature), 0x61417272);
269 if (
i.boot_sign !=
htole32(0xaa550000))
270 printf(
" Offset %llu: 0x%08x != expected 0x%08x\n",
272 le32toh(
i.boot_sign), 0xaa550000);
274 printf(
"1) Correct\n2) Don't correct (FSINFO invalid then)\n");
276 printf(
" Auto-correcting it.\n");
281 fs->fsinfo_start = 0;
284 if (
fs->fsinfo_start)
285 fs->free_clusters = le32toh(
i.free_clusters);
290 printf(
"Dirty bit is set. Fs was not properly unmounted and"
291 " some data may be corrupt.\n");
294 printf(
"1) Remove dirty bit\n" "2) No action\n");
301 printf(
" Automatically removing dirty bit.\n");
311 if (
fs->fat_bits == 32) {
337 unsigned total_sectors;
338 unsigned int logical_sector_size,
sectors;
340 unsigned total_fat_entries;
345 if (!logical_sector_size)
346 die(
"Logical sector size is zero.");
352 die(
"Logical sector size (%d bytes) is not a multiple of the physical "
353 "sector size.", logical_sector_size);
355 fs->cluster_size =
b.cluster_size * logical_sector_size;
356 if (!
fs->cluster_size)
357 die(
"Cluster size is zero.");
358 if (
b.fats != 2 &&
b.fats != 1)
359 die(
"Currently, only 1 or 2 FATs are supported, not %d.\n",
b.fats);
364 printf(
"Checking we can access the last sector of the filesystem\n");
366 fs_test((
off_t)((total_sectors & ~1) - 1) * logical_sector_size,
367 logical_sector_size);
370 le16toh(
b.fat_length) : le32toh(
b.fat32_length);
372 die(
"FAT size is zero.");
374 fs->fat_start = (
off_t)le16toh(
b.reserved) * logical_sector_size;
380 logical_sector_size);
382 data_size = (
off_t)total_sectors * logical_sector_size -
fs->data_start;
384 die(
"Filesystem has no space for any data clusters");
386 fs->data_clusters = data_size /
fs->cluster_size;
387 fs->root_cluster = 0;
388 fs->fsinfo_start = 0;
389 fs->free_clusters = -1;
390 if (!
b.fat_length &&
b.fat32_length) {
392 fs->root_cluster = le32toh(
b.root_cluster);
393 if (!
fs->root_cluster &&
fs->root_entries)
399 printf(
"Warning: FAT32 root dir not in cluster chain! "
400 "Compatibility mode...\n");
401 else if (!
fs->root_cluster && !
fs->root_entries)
402 die(
"No root directory!");
403 else if (
fs->root_cluster &&
fs->root_entries)
404 printf(
"Warning: FAT32 root dir is in a cluster chain, but "
405 "a separate root dir\n"
406 " area is defined. Cannot fix this easily.\n");
408 printf(
"Warning: Filesystem is FAT32 according to fat_length "
409 "and fat32_length fields,\n"
410 " but has only %lu clusters, less than the required "
412 " This may lead to problems on some systems.\n",
416 fs->backupboot_start = le16toh(
b.backup_boot) * logical_sector_size;
425 die(
"Too many clusters (%lu) for FAT16 filesystem.",
426 (
unsigned long)
fs->data_clusters);
434 if (
fs->data_clusters + 2 >
fat_length * logical_sector_size * 8 / 16 ||
436 (total_sectors == 720 || total_sectors == 1440 ||
437 total_sectors == 2880))
441 fs->eff_fat_bits = (
fs->fat_bits == 32) ? 28 :
fs->fat_bits;
445 if (
fs->fat_bits == 12 ||
fs->fat_bits == 16) {
458 }
else if (
fs->fat_bits == 32) {
459 if (
b.extended_sig == 0x29)
472 total_fat_entries = (
uint64_t)
fs->fat_size * 8 /
fs->fat_bits;
473 if (
fs->data_clusters > total_fat_entries - 2)
474 die(
"Filesystem has %u clusters but only space for %u FAT entries.",
475 fs->data_clusters, total_fat_entries - 2);
476 if (!
fs->root_entries && !
fs->root_cluster)
477 die(
"Root directory has zero size.");
479 die(
"Root directory (%d entries) doesn't span an integral number of "
480 "sectors.",
fs->root_entries);
482 die(
"Logical sector size (%u bytes) is not a multiple of the physical "
483 "sector size.", logical_sector_size);
487 die(
"Invalid disk format in boot sector.");
496 if (
fs->fat_bits == 12 ||
fs->fat_bits == 16) {
508 }
else if (
fs->fat_bits == 32) {
512 if (
b.extended_sig != 0x29) {
513 b.extended_sig = 0x29;
519 if (
fs->backupboot_start)
530 if (
fs->root_cluster) {
531 for (cluster =
fs->root_cluster;
532 cluster != 0 && cluster != -1;
535 for (
i = 0;
i *
sizeof(DIR_ENT) <
fs->cluster_size;
i++) {
539 offset +=
sizeof(DIR_ENT);
543 for (
i = 0;
i <
fs->root_entries;
i++) {
544 offset =
fs->root_start +
i *
sizeof(DIR_ENT);
573 ((mtime->
tm_mon + 1) << 5) +
574 ((mtime->
tm_year - 80) << 9)));
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
ACPI_SIZE strlen(const char *String)
off_t alloc_rootdir_entry(DOS_FS *fs, DIR_ENT *de, const char *pattern, int gen_name)
GLdouble GLdouble GLdouble GLdouble q
GLboolean GLboolean GLboolean b
GLenum GLuint GLenum GLsizei const GLchar * buf
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
#define memcpy(s1, s2, n)
#define memmove(s1, s2, n)
#define sprintf(buf, format,...)
static const WCHAR label[]
static CRYPT_DATA_BLOB b2[]
NTSTRSAFEVAPI RtlStringCbPrintfA(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cbDest, _In_ _Printf_format_string_ NTSTRSAFE_PCSTR pszFormat,...)
#define offsetof(TYPE, MEMBER)
_CRTIMP struct tm *__cdecl localtime(const time_t *_Time)
static char print_fat_dirty_state(void)
void write_label(DOS_FS *fs, char *label)
static const char * get_media_descr(unsigned char media)
static void read_fsinfo(DOS_FS *fs, struct boot_sector *b, unsigned int lss)
static void check_backup_boot(DOS_FS *fs, struct boot_sector *b, unsigned int lss)
static void write_boot_label(DOS_FS *fs, char *label)
#define ROUND_TO_MULTIPLE(n, m)
off_t find_volume_de(DOS_FS *fs, DIR_ENT *de)
#define GET_UNALIGNED_W(f)
void read_boot(DOS_FS *fs)
static void init_fsinfo(struct info_sector *i)
static void check_fat_state_bit(DOS_FS *fs, void *b)
static struct @5002 mediabytes[]
static void write_volume_label(DOS_FS *fs, char *label)
static void dump_boot(DOS_FS *fs, struct boot_sector *b, unsigned lss)
char get_key(const char *valid, const char *prompt)
uint32_t next_cluster(DOS_FS *fs, uint32_t cluster)
off_t cluster_start(DOS_FS *fs, uint32_t cluster)
int fs_test(off_t pos, int size)
void fs_read(off_t pos, int size, void *data)
void fs_write(off_t pos, int size, void *data)