ReactOS 0.4.15-dev-8222-g9164419
boot.c
Go to the documentation of this file.
1/* boot.c - Read and analyze ia PC/MS-DOS boot sector
2
3 Copyright (C) 1993 Werner Almesberger <werner.almesberger@lrc.di.epfl.ch>
4 Copyright (C) 1998 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>
5 Copyright (C) 2008-2014 Daniel Baumann <mail@daniel-baumann.ch>
6 Copyright (C) 2015 Andreas Bombe <aeb@debian.org>
7
8 This program is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
20
21 The complete text of the GNU General Public License
22 can be found in /usr/share/common-licenses/GPL-3 file.
23*/
24
25/* FAT32, VFAT, Atari format support, and various fixes additions May 1998
26 * by Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> */
27
28#include "vfatlib.h"
29#ifdef __REACTOS__
30#include <ntstrsafe.h>
31#endif // __REACTOS__
32
33#define NDEBUG
34#include <debug.h>
35
36#define ROUND_TO_MULTIPLE(n,m) ((n) && (m) ? (n)+(m)-1-((n)-1)%(m) : 0)
37 /* don't divide by zero */
38
39/* cut-over cluster counts for FAT12 and FAT16 */
40#define FAT12_THRESHOLD 4085
41#define FAT16_THRESHOLD 65525
42
43static struct {
45 const char *descr;
46} mediabytes[] = {
47 {
48 0xf0, "5.25\" or 3.5\" HD floppy"}, {
49 0xf8, "hard disk"}, {
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"},};
58
59/* Unaligned fields must first be accessed byte-wise */
60#define GET_UNALIGNED_W(f) \
61 ( (uint16_t)f[0] | ((uint16_t)f[1]<<8) )
62
63static const char *get_media_descr(unsigned char media)
64{
65 int i;
66
67 for (i = 0; i < sizeof(mediabytes) / sizeof(*mediabytes); ++i) {
68 if (mediabytes[i].media == media)
69 return (mediabytes[i].descr);
70 }
71 return ("undefined");
72}
73
74static void dump_boot(DOS_FS * fs, struct boot_sector *b, unsigned lss)
75{
76 unsigned short sectors;
77
78 printf("Boot sector contents:\n");
79 if (!atari_format) {
80 char id[9];
81 strncpy(id, (const char *)b->system_id, 8);
82 id[8] = 0;
83 printf("System ID \"%s\"\n", id);
84 } else {
85 /* On Atari, a 24 bit serial number is stored at offset 8 of the boot
86 * sector */
87 printf("Serial number 0x%x\n",
88 b->system_id[5] | (b->system_id[6] << 8) | (b->
89 system_id[7] << 16));
90 }
91 printf("Media byte 0x%02x (%s)\n", b->media, get_media_descr(b->media));
92 printf("%10d bytes per logical sector\n", GET_UNALIGNED_W(b->sector_size));
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);
107 } else {
108 printf("Root directory start at cluster %lu (arbitrary size)\n",
109 (unsigned long)fs->root_cluster);
110 }
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),
118 le16toh(b->heads));
119 printf("%10u hidden sectors\n", atari_format ?
120 /* On Atari, the hidden field is only 16 bit wide and unused */
121 (((unsigned char *)&b->hidden)[0] |
122 ((unsigned char *)&b->hidden)[1] << 8) : le32toh(b->hidden));
123 sectors = GET_UNALIGNED_W(b->sectors);
124 printf("%10u sectors total\n", sectors ? sectors : le32toh(b->total_sect));
125}
126
127static void check_backup_boot(DOS_FS * fs, struct boot_sector *b, unsigned int lss)
128{
129 struct boot_sector b2;
130
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");
135 return;
136 }
137 if (interactive)
138 printf("1) Create one\n2) Do without a backup\n");
139 else
140 printf(" Auto-creating backup boot block.\n");
141 if (!interactive || get_key("12", "?") == '1') {
142 unsigned int bbs;
143 /* The usual place for the backup boot sector is sector 6. Choose
144 * that or the last reserved sector. */
145 if (le16toh(b->reserved) >= 7 && le16toh(b->info_sector) != 6)
146 bbs = 6;
147 else {
148 bbs = le16toh(b->reserved) - 1;
149 if (bbs == le16toh(b->info_sector))
150 --bbs; /* this is never 0, as we checked reserved >= 3! */
151 }
152 fs->backupboot_start = bbs * lss;
153 b->backup_boot = htole16(bbs);
154 fs_write(fs->backupboot_start, sizeof(*b), b);
156 sizeof(b->backup_boot), &b->backup_boot);
157 printf("Created backup of boot sector in sector %d\n", bbs);
158 return;
159 } else
160 return;
161 }
162
163 fs_read(fs->backupboot_start, sizeof(b2), &b2);
164 if (memcmp(b, &b2, sizeof(b2)) != 0) {
165 /* there are any differences */
166 uint8_t *p, *q;
167 int i, pos, first = 1;
168 char buf[20];
169
170 printf("There are differences between boot sector and its backup.\n");
171 printf("This is mostly harmless. Differences: (offset:original/backup)\n ");
172 pos = 2;
173 for (p = (uint8_t *) b, q = (uint8_t *) & b2, i = 0; i < sizeof(b2);
174 ++p, ++q, ++i) {
175 if (*p != *q) {
176#ifndef __REACTOS__
177 sprintf(buf, "%s%u:%02x/%02x", first ? "" : ", ",
178#else
179 RtlStringCbPrintfA(buf, sizeof(buf), "%s%u:%02x/%02x", first ? "" : ", ",
180#endif // __REACTOS__
181 (unsigned)(p - (uint8_t *) b), *p, *q);
182 if (pos + strlen(buf) > 78)
183 printf("\n "), pos = 2;
184 printf("%s", buf);
185 pos += strlen(buf);
186 first = 0;
187 }
188 }
189 printf("\n");
190
191 if (interactive)
192 printf("1) Copy original to backup\n"
193 "2) Copy backup to original\n" "3) No action\n");
194 else
195 printf(" Not automatically fixing this.\n");
196 switch (interactive ? get_key("123", "?") : '3') {
197 case '1':
198 fs_write(fs->backupboot_start, sizeof(*b), b);
199 break;
200 case '2':
201 fs_write(0, sizeof(b2), &b2);
202 break;
203 default:
204 break;
205 }
206 }
207}
208
209static void init_fsinfo(struct info_sector *i)
210{
211 memset(i, 0, sizeof (struct info_sector));
212 i->magic = htole32(0x41615252);
213 i->signature = htole32(0x61417272);
214 i->free_clusters = htole32(-1);
215 i->next_cluster = htole32(2);
216 i->boot_sign = htole32(0xaa550000);
217}
218
219static void read_fsinfo(DOS_FS * fs, struct boot_sector *b, unsigned int lss)
220{
221 struct info_sector i;
222
223 if (!b->info_sector) {
224 printf("No FSINFO sector\n");
225 if (interactive)
226 printf("1) Create one\n2) Do without FSINFO\n");
227 else
228 printf(" Not automatically creating it.\n");
229 if (interactive && get_key("12", "?") == '1') {
230 /* search for a free reserved sector (not boot sector and not
231 * backup boot sector) */
232 uint32_t s;
233 for (s = 1; s < le16toh(b->reserved); ++s)
234 if (s != le16toh(b->backup_boot))
235 break;
236 if (s > 0 && s < le16toh(b->reserved)) {
237 init_fsinfo(&i);
238 fs_write((off_t)s * lss, sizeof(i), &i);
239 b->info_sector = htole16(s);
241 sizeof(b->info_sector), &b->info_sector);
242 if (fs->backupboot_start)
243 fs_write(fs->backupboot_start +
245 sizeof(b->info_sector), &b->info_sector);
246 } else {
247 printf("No free reserved sector found -- "
248 "no space for FSINFO sector!\n");
249 return;
250 }
251 } else
252 return;
253 }
254
255 fs->fsinfo_start = le16toh(b->info_sector) * lss;
256 fs_read(fs->fsinfo_start, sizeof(i), &i);
257
258 if (i.magic != htole32(0x41615252) ||
259 i.signature != htole32(0x61417272) || i.boot_sign != htole32(0xaa550000)) {
260 printf("FSINFO sector has bad magic number(s):\n");
261 if (i.magic != htole32(0x41615252))
262 printf(" Offset %llu: 0x%08x != expected 0x%08x\n",
263 (unsigned long long)offsetof(struct info_sector, magic),
264 le32toh(i.magic), 0x41615252);
265 if (i.signature != htole32(0x61417272))
266 printf(" Offset %llu: 0x%08x != expected 0x%08x\n",
267 (unsigned long long)offsetof(struct info_sector, signature),
268 le32toh(i.signature), 0x61417272);
269 if (i.boot_sign != htole32(0xaa550000))
270 printf(" Offset %llu: 0x%08x != expected 0x%08x\n",
271 (unsigned long long)offsetof(struct info_sector, boot_sign),
272 le32toh(i.boot_sign), 0xaa550000);
273 if (interactive)
274 printf("1) Correct\n2) Don't correct (FSINFO invalid then)\n");
275 else
276 printf(" Auto-correcting it.\n");
277 if (!interactive || get_key("12", "?") == '1') {
278 init_fsinfo(&i);
279 fs_write(fs->fsinfo_start, sizeof(i), &i);
280 } else
281 fs->fsinfo_start = 0;
282 }
283
284 if (fs->fsinfo_start)
285 fs->free_clusters = le32toh(i.free_clusters);
286}
287
288static char print_fat_dirty_state(void)
289{
290 printf("Dirty bit is set. Fs was not properly unmounted and"
291 " some data may be corrupt.\n");
292
293 if (interactive) {
294 printf("1) Remove dirty bit\n" "2) No action\n");
295 return get_key("12", "?");
296#ifndef __REACTOS__
297 } else
298#else
299 } else if (rw) {
300#endif
301 printf(" Automatically removing dirty bit.\n");
302 return '1';
303#ifdef __REACTOS__
304 }
305 return '2';
306#endif
307}
308
309static void check_fat_state_bit(DOS_FS * fs, void *b)
310{
311 if (fs->fat_bits == 32) {
312 struct boot_sector *b32 = b;
313
314 if (b32->reserved3 & FAT_STATE_DIRTY) {
315 printf("0x41: ");
316 if (print_fat_dirty_state() == '1') {
317 b32->reserved3 &= ~FAT_STATE_DIRTY;
318 fs_write(0, sizeof(*b32), b32);
319 }
320 }
321 } else {
322 struct boot_sector_16 *b16 = b;
323
324 if (b16->reserved2 & FAT_STATE_DIRTY) {
325 printf("0x25: ");
326 if (print_fat_dirty_state() == '1') {
327 b16->reserved2 &= ~FAT_STATE_DIRTY;
328 fs_write(0, sizeof(*b16), b16);
329 }
330 }
331 }
332}
333
335{
336 struct boot_sector b;
337 unsigned total_sectors;
338 unsigned int logical_sector_size, sectors;
340 unsigned total_fat_entries;
341 off_t data_size;
342
343 fs_read(0, sizeof(b), &b);
344 logical_sector_size = GET_UNALIGNED_W(b.sector_size);
345 if (!logical_sector_size)
346 die("Logical sector size is zero.");
347
348 /* This was moved up because it's the first thing that will fail */
349 /* if the platform needs special handling of unaligned multibyte accesses */
350 /* but such handling isn't being provided. See GET_UNALIGNED_W() above. */
351 if (logical_sector_size & (SECTOR_SIZE - 1))
352 die("Logical sector size (%d bytes) is not a multiple of the physical "
353 "sector size.", logical_sector_size);
354
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);
360 fs->nfats = b.fats;
361 sectors = GET_UNALIGNED_W(b.sectors);
362 total_sectors = sectors ? sectors : le32toh(b.total_sect);
363 if (verbose)
364 printf("Checking we can access the last sector of the filesystem\n");
365 /* Can't access last odd sector anyway, so round down */
366 fs_test((off_t)((total_sectors & ~1) - 1) * logical_sector_size,
367 logical_sector_size);
368
369 fat_length = le16toh(b.fat_length) ?
370 le16toh(b.fat_length) : le32toh(b.fat32_length);
371 if (!fat_length)
372 die("FAT size is zero.");
373
374 fs->fat_start = (off_t)le16toh(b.reserved) * logical_sector_size;
375 fs->root_start = ((off_t)le16toh(b.reserved) + b.fats * fat_length) *
376 logical_sector_size;
377 fs->root_entries = GET_UNALIGNED_W(b.dir_entries);
378 fs->data_start = fs->root_start + ROUND_TO_MULTIPLE(fs->root_entries <<
380 logical_sector_size);
381
382 data_size = (off_t)total_sectors * logical_sector_size - fs->data_start;
383 if (data_size < fs->cluster_size)
384 die("Filesystem has no space for any data clusters");
385
386 fs->data_clusters = data_size / fs->cluster_size;
387 fs->root_cluster = 0; /* indicates standard, pre-FAT32 root dir */
388 fs->fsinfo_start = 0; /* no FSINFO structure */
389 fs->free_clusters = -1; /* unknown */
390 if (!b.fat_length && b.fat32_length) {
391 fs->fat_bits = 32;
392 fs->root_cluster = le32toh(b.root_cluster);
393 if (!fs->root_cluster && fs->root_entries)
394 /* M$ hasn't specified this, but it looks reasonable: If
395 * root_cluster is 0 but there is a separate root dir
396 * (root_entries != 0), we handle the root dir the old way. Give a
397 * warning, but convertig to a root dir in a cluster chain seems
398 * to complex for now... */
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");
407 if (fs->data_clusters < FAT16_THRESHOLD)
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 "
411 "minimum of %d.\n"
412 " This may lead to problems on some systems.\n",
413 (unsigned long)fs->data_clusters, FAT16_THRESHOLD);
414
416 fs->backupboot_start = le16toh(b.backup_boot) * logical_sector_size;
417 check_backup_boot(fs, &b, logical_sector_size);
418
419 read_fsinfo(fs, &b, logical_sector_size);
420 } else if (!atari_format) {
421 /* On real MS-DOS, a 16 bit FAT is used whenever there would be too
422 * much clusers otherwise. */
423 fs->fat_bits = (fs->data_clusters >= FAT12_THRESHOLD) ? 16 : 12;
424 if (fs->data_clusters >= FAT16_THRESHOLD)
425 die("Too many clusters (%lu) for FAT16 filesystem.",
426 (unsigned long)fs->data_clusters);
428 } else {
429 /* On Atari, things are more difficult: GEMDOS always uses 12bit FATs
430 * on floppies, and always 16 bit on harddisks. */
431 fs->fat_bits = 16; /* assume 16 bit FAT for now */
432 /* If more clusters than fat entries in 16-bit fat, we assume
433 * it's a real MSDOS FS with 12-bit fat. */
434 if (fs->data_clusters + 2 > fat_length * logical_sector_size * 8 / 16 ||
435 /* if it has one of the usual floppy sizes -> 12bit FAT */
436 (total_sectors == 720 || total_sectors == 1440 ||
437 total_sectors == 2880))
438 fs->fat_bits = 12;
439 }
440 /* On FAT32, the high 4 bits of a FAT entry are reserved */
441 fs->eff_fat_bits = (fs->fat_bits == 32) ? 28 : fs->fat_bits;
442 fs->fat_size = fat_length * logical_sector_size;
443
444 fs->label = calloc(12, sizeof(uint8_t));
445 if (fs->fat_bits == 12 || fs->fat_bits == 16) {
446 struct boot_sector_16 *b16 = (struct boot_sector_16 *)&b;
447 if (b16->extended_sig == 0x29)
448 memmove(fs->label, b16->label, 11);
449 else
450#ifdef __REACTOS__
451 {
452 free(fs->label);
453#endif
454 fs->label = NULL;
455#ifdef __REACTOS__
456 }
457#endif
458 } else if (fs->fat_bits == 32) {
459 if (b.extended_sig == 0x29)
460 memmove(fs->label, &b.label, 11);
461 else
462#ifdef __REACTOS__
463 {
464 free(fs->label);
465#endif
466 fs->label = NULL;
467#ifdef __REACTOS__
468 }
469#endif
470 }
471
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.");
478 if (fs->root_entries & (MSDOS_DPS - 1))
479 die("Root directory (%d entries) doesn't span an integral number of "
480 "sectors.", fs->root_entries);
481 if (logical_sector_size & (SECTOR_SIZE - 1))
482 die("Logical sector size (%u bytes) is not a multiple of the physical "
483 "sector size.", logical_sector_size);
484#if 0 /* linux kernel doesn't check that either */
485 /* ++roman: On Atari, these two fields are often left uninitialized */
486 if (!atari_format && (!b.secs_track || !b.heads))
487 die("Invalid disk format in boot sector.");
488#endif
489 if (verbose)
490 dump_boot(fs, &b, logical_sector_size);
491}
492
493#ifndef __REACTOS__
494static void write_boot_label(DOS_FS * fs, char *label)
495{
496 if (fs->fat_bits == 12 || fs->fat_bits == 16) {
497 struct boot_sector_16 b16;
498
499 fs_read(0, sizeof(b16), &b16);
500 if (b16.extended_sig != 0x29) {
501 b16.extended_sig = 0x29;
502 b16.serial = 0;
503 memmove(b16.fs_type, fs->fat_bits == 12 ? "FAT12 " : "FAT16 ",
504 8);
505 }
506 memmove(b16.label, label, 11);
507 fs_write(0, sizeof(b16), &b16);
508 } else if (fs->fat_bits == 32) {
509 struct boot_sector b;
510
511 fs_read(0, sizeof(b), &b);
512 if (b.extended_sig != 0x29) {
513 b.extended_sig = 0x29;
514 b.serial = 0;
515 memmove(b.fs_type, "FAT32 ", 8);
516 }
517 memmove(b.label, label, 11);
518 fs_write(0, sizeof(b), &b);
519 if (fs->backupboot_start)
520 fs_write(fs->backupboot_start, sizeof(b), &b);
521 }
522}
523
525{
526 uint32_t cluster;
528 int i;
529
530 if (fs->root_cluster) {
531 for (cluster = fs->root_cluster;
532 cluster != 0 && cluster != -1;
533 cluster = next_cluster(fs, cluster)) {
534 offset = cluster_start(fs, cluster);
535 for (i = 0; i * sizeof(DIR_ENT) < fs->cluster_size; i++) {
536 fs_read(offset, sizeof(DIR_ENT), de);
537 if (de->attr != VFAT_LN_ATTR && de->attr & ATTR_VOLUME)
538 return offset;
539 offset += sizeof(DIR_ENT);
540 }
541 }
542 } else {
543 for (i = 0; i < fs->root_entries; i++) {
544 offset = fs->root_start + i * sizeof(DIR_ENT);
545 fs_read(offset, sizeof(DIR_ENT), de);
546 if (de->attr != VFAT_LN_ATTR && de->attr & ATTR_VOLUME)
547 return offset;
548 }
549 }
550
551 return 0;
552}
553
554static void write_volume_label(DOS_FS * fs, char *label)
555{
556 time_t now = time(NULL);
557 struct tm *mtime = localtime(&now);
559 int created;
560 DIR_ENT de;
561
562 created = 0;
563 offset = find_volume_de(fs, &de);
564 if (offset == 0) {
565 created = 1;
567 }
568 memcpy(de.name, label, 11);
569 de.time = htole16((unsigned short)((mtime->tm_sec >> 1) +
570 (mtime->tm_min << 5) +
571 (mtime->tm_hour << 11)));
572 de.date = htole16((unsigned short)(mtime->tm_mday +
573 ((mtime->tm_mon + 1) << 5) +
574 ((mtime->tm_year - 80) << 9)));
575 if (created) {
576 de.attr = ATTR_VOLUME;
577 de.ctime_ms = 0;
578 de.ctime = de.time;
579 de.cdate = de.date;
580 de.adate = de.date;
581 de.starthi = 0;
582 de.start = 0;
583 de.size = 0;
584 }
585
586 fs_write(offset, sizeof(DIR_ENT), &de);
587}
588
590{
591 int l = strlen(label);
592
593 while (l < 11)
594 label[l++] = ' ';
595
598}
599#endif
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strncpy(char *DstString, const char *SrcString, ACPI_SIZE Count)
Definition: utclib.c:427
#define SECTOR_SIZE
Definition: fs.h:22
r l[0]
Definition: byte_order.h:168
#define free
Definition: debug_ros.c:5
#define NULL
Definition: types.h:112
UINT32 uint32_t
Definition: types.h:75
#define off_t
Definition: dosfsck.h:5
__kernel_time_t time_t
Definition: linux.h:252
__kernel_off_t off_t
Definition: linux.h:201
time_t now
Definition: finger.c:65
#define printf
Definition: freeldr.h:97
#define FAT_STATE_DIRTY
Definition: fsck.fat.h:80
#define VFAT_LN_ATTR
Definition: fsck.fat.h:78
off_t alloc_rootdir_entry(DOS_FS *fs, DIR_ENT *de, const char *pattern, int gen_name)
Definition: check.c:74
GLdouble s
Definition: gl.h:2039
GLdouble GLdouble GLdouble GLdouble q
Definition: gl.h:2063
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
const GLint * first
Definition: glext.h:5794
GLfloat GLfloat p
Definition: glext.h:8902
GLintptr offset
Definition: glext.h:5920
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
Definition: glfuncs.h:248
#define b
Definition: ke_i.h:79
if(dx< 0)
Definition: linetemp.h:194
__u16 fat_length
Definition: mkdosfs.c:10
__u8 cluster_size
Definition: mkdosfs.c:4
#define die(str)
Definition: mkdosfs.c:347
__u16 time
Definition: mkdosfs.c:8
__u8 system_id[8]
Definition: mkdosfs.c:1
static int backup_boot
Definition: mkdosfs.c:530
#define ATTR_VOLUME
Definition: mkdosfs.c:369
__u8 sectors[2]
Definition: mkdosfs.c:8
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
#define sprintf(buf, format,...)
Definition: sprintf.c:55
static const WCHAR label[]
Definition: itemdlg.c:1546
static CRYPT_DATA_BLOB b2[]
Definition: msg.c:582
#define MSDOS_DPS
Definition: msdos_fs.h:28
#define MSDOS_DIR_BITS
Definition: msdos_fs.h:30
BYTE uint8_t
Definition: msvideo1.c:66
u32_t magic(void)
#define uint64_t
Definition: nsiface.idl:62
NTSTRSAFEVAPI RtlStringCbPrintfA(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cbDest, _In_ _Printf_format_string_ NTSTRSAFE_PCSTR pszFormat,...)
Definition: ntstrsafe.h:1148
#define atari_format
Definition: rosglue.h:41
#define calloc
Definition: rosglue.h:14
#define rw
Definition: rosglue.h:38
#define interactive
Definition: rosglue.h:34
#define verbose
Definition: rosglue.h:36
#define offsetof(TYPE, MEMBER)
_CRTIMP struct tm *__cdecl localtime(const time_t *_Time)
Definition: time.h:416
static char print_fat_dirty_state(void)
Definition: boot.c:288
void write_label(DOS_FS *fs, char *label)
Definition: boot.c:589
#define FAT16_THRESHOLD
Definition: boot.c:41
static const char * get_media_descr(unsigned char media)
Definition: boot.c:63
static void read_fsinfo(DOS_FS *fs, struct boot_sector *b, unsigned int lss)
Definition: boot.c:219
static struct @4971 mediabytes[]
static void check_backup_boot(DOS_FS *fs, struct boot_sector *b, unsigned int lss)
Definition: boot.c:127
static void write_boot_label(DOS_FS *fs, char *label)
Definition: boot.c:494
#define FAT12_THRESHOLD
Definition: boot.c:40
#define ROUND_TO_MULTIPLE(n, m)
Definition: boot.c:36
off_t find_volume_de(DOS_FS *fs, DIR_ENT *de)
Definition: boot.c:524
#define GET_UNALIGNED_W(f)
Definition: boot.c:60
void read_boot(DOS_FS *fs)
Definition: boot.c:334
uint8_t media
Definition: boot.c:44
static void init_fsinfo(struct info_sector *i)
Definition: boot.c:209
const char * descr
Definition: boot.c:45
static void check_fat_state_bit(DOS_FS *fs, void *b)
Definition: boot.c:309
static void write_volume_label(DOS_FS *fs, char *label)
Definition: boot.c:554
static void dump_boot(DOS_FS *fs, struct boot_sector *b, unsigned lss)
Definition: boot.c:74
char get_key(const char *valid, const char *prompt)
Definition: common.c:184
uint32_t next_cluster(DOS_FS *fs, uint32_t cluster)
Definition: fat.c:276
off_t cluster_start(DOS_FS *fs, uint32_t cluster)
Definition: fat.c:289
int fs_test(off_t pos, int size)
Definition: io.c:322
void fs_read(off_t pos, int size, void *data)
Definition: io.c:282
void fs_write(off_t pos, int size, void *data)
Definition: io.c:344
#define memset(x, y, z)
Definition: compat.h:39
#define htole16(x)
Definition: storage32.h:546
#define htole32(x)
Definition: storage32.h:543
uint8_t fs_type[8]
Definition: fsck.fat.h:149
uint8_t extended_sig
Definition: fsck.fat.h:146
uint8_t label[11]
Definition: fsck.fat.h:148
uint32_t serial
Definition: fsck.fat.h:147
uint8_t reserved2
Definition: fsck.fat.h:144
uint8_t reserved3
Definition: fsck.fat.h:115
Definition: ffs.h:70
uint32_t boot_sign
Definition: fsck.fat.h:162
uint32_t signature
Definition: fsck.fat.h:158
Definition: time.h:68
int tm_mon
Definition: time.h:73
int tm_year
Definition: time.h:74
int tm_hour
Definition: time.h:71
int tm_sec
Definition: time.h:69
int tm_mday
Definition: time.h:72
int tm_min
Definition: time.h:70