Author: oxygene
Date: 2008-09-30 11:42:37 +0200 (Tue, 30 Sep 2008)
New Revision: 70
Modified:
trunk/filo/fs/fat.h
trunk/filo/fs/fsys_fat.c
Log:
take a closer look at the filesystem before interpreting it as FAT.
fixes #1
Modified: trunk/filo/fs/fat.h
===================================================================
--- trunk/filo/fs/fat.h 2008-09-29 17:47:50 UTC (rev 69)
+++ trunk/filo/fs/fat.h 2008-09-30 09:42:37 UTC (rev 70)
@@ -1,6 +1,7 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2001 Free Software Foundation, Inc.
+ * Copyright (C) 2008 coresystems GmbH
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -30,6 +31,35 @@
typedef __signed__ int __s32;
typedef unsigned int __u32;
+
+struct fat16_extended_bpb {
+ __u8 drive_number; /* Physical Drive Number */
+ __u8 reserved; /* "current head" */
+ __u8 boot_signature; /* Extended Boot Signature 0x28 or 0x29 */
+ __u8 id[4]; /* ID (serial number) */
+ __u8 volumelabel[11];/* volume label */
+ __s8 type[8]; /* Padded with blanks: "FAT12", "FAT16" */
+} __attribute__((packed));
+
+struct fat32_extended_bpb {
+ /* The following fields are only used by FAT32 */
+ __u32 fat32_length; /* sectors/FAT */
+ __u16 flags; /* bit 8: fat mirroring, low 4: active fat */
+ __u8 version[2]; /* major, minor filesystem version */
+ __u32 root_cluster; /* first cluster in root directory */
+ __u16 info_sector; /* filesystem info sector */
+ __u16 backup_boot; /* backup boot sector */
+ __u16 reserved2[12]; /* Reserved */
+ /* from here on it looks like the fat12/fat16 code */
+ __u8 drive_number; /* Physical Drive Number */
+ __u8 reserved; /* "current head" */
+ __u8 boot_signature; /* Extended Boot Signature 0x28 or 0x29 */
+ __u8 id[4]; /* ID (serial number) */
+ __u8 volumelabel[11];/* volume label */
+ __s8 type[8]; /* Padded with blanks: "FAT32" */
+} __attribute__((packed));
+
+
/* Note that some shorts are not aligned, and must therefore
* be declared as array of two bytes.
*/
@@ -50,14 +80,10 @@
__u32 hidden; /* hidden sectors (unused) */
__u32 long_sectors; /* number of sectors (if short_sectors == 0) */
- /* The following fields are only used by FAT32 */
- __u32 fat32_length; /* sectors/FAT */
- __u16 flags; /* bit 8: fat mirroring, low 4: active fat */
- __u8 version[2]; /* major, minor filesystem version */
- __u32 root_cluster; /* first cluster in root directory */
- __u16 info_sector; /* filesystem info sector */
- __u16 backup_boot; /* backup boot sector */
- __u16 reserved2[6]; /* Unused */
+ union {
+ struct fat16_extended_bpb fat16;
+ struct fat32_extended_bpb fat32;
+ } extended;
};
#define FAT_CVT_U16(bytarr) (* (__u16*)(bytarr))
Modified: trunk/filo/fs/fsys_fat.c
===================================================================
--- trunk/filo/fs/fsys_fat.c 2008-09-29 17:47:50 UTC (rev 69)
+++ trunk/filo/fs/fsys_fat.c 2008-09-30 09:42:37 UTC (rev 70)
@@ -83,7 +83,7 @@
/* FAT offset and length */
FAT_SUPER->fat_offset = FAT_CVT_U16 (bpb.reserved_sects);
FAT_SUPER->fat_length =
- bpb.fat_length ? bpb.fat_length : bpb.fat32_length;
+ bpb.fat_length ? bpb.fat_length : bpb.extended.fat32.fat32_length;
/* Rootdir offset and length for FAT12/16 */
FAT_SUPER->root_offset =
@@ -99,23 +99,31 @@
/ bpb.sects_per_clust);
FAT_SUPER->sects_per_clust = bpb.sects_per_clust;
+ if (strncmp(bpb.extended.fat16.type, "FAT12", 5) &&
+ strncmp(bpb.extended.fat16.type, "FAT16", 5) &&
+ strncmp(bpb.extended.fat32.type, "FAT32", 5))
+ {
+ /* None of them matched. Bail out */
+ return 0;
+ }
+
if (!bpb.fat_length)
{
/* This is a FAT32 */
if (FAT_CVT_U16(bpb.dir_entries))
return 0;
- if (bpb.flags & 0x0080)
+ if (bpb.extended.fat32.flags & 0x0080)
{
/* FAT mirroring is disabled, get active FAT */
- int active_fat = bpb.flags & 0x000f;
+ int active_fat = bpb.extended.fat32.flags & 0x000f;
if (active_fat >= bpb.num_fats)
return 0;
FAT_SUPER->fat_offset += active_fat * FAT_SUPER->fat_length;
}
FAT_SUPER->fat_size = 8;
- FAT_SUPER->root_cluster = bpb.root_cluster;
+ FAT_SUPER->root_cluster = bpb.extended.fat32.root_cluster;
/* Yes the following is correct. FAT32 should be called FAT28 :) */
FAT_SUPER->clust_eof_marker = 0xffffff8;