1 /*
   2     libparted
   3     Copyright (C) 1998, 1999, 2000, 2007 Free Software Foundation, Inc.
   4 
   5     This program is free software; you can redistribute it and/or modify
   6     it under the terms of the GNU General Public License as published by
   7     the Free Software Foundation; either version 3 of the License, or
   8     (at your option) any later version.
   9 
  10     This program is distributed in the hope that it will be useful,
  11     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13     GNU General Public License for more details.
  14 
  15     You should have received a copy of the GNU General Public License
  16     along with this program.  If not, see <http://www.gnu.org/licenses/>.
  17 */
  18 
  19 #ifndef PED_FAT_BOOTSECTOR_H
  20 #define PED_FAT_BOOTSECTOR_H
  21 
  22 typedef struct _FatBootSector   FatBootSector;
  23 typedef struct _FatInfoSector   FatInfoSector;
  24 
  25 #include "fat.h"
  26 
  27 #define FAT32_INFO_MAGIC1       0x41615252
  28 #define FAT32_INFO_MAGIC2       0x61417272
  29 #define FAT32_INFO_MAGIC3       0xaa55
  30 
  31 /* stolen from mkdosfs, by Dave Hudson */
  32 
  33 #define FAT_BOOT_MESSAGE        \
  34 "This partition does not have an operating system loader installed on it.\n\r"\
  35 "Press a key to reboot..."
  36 
  37 #define FAT_BOOT_JUMP   "\xeb\x58\x90"          /* jmp  +5a */
  38 
  39 #define FAT_BOOT_CODE   "\x0e"                  /* push cs */           \
  40                         "\x1f"                  /* pop ds */            \
  41                         "\xbe\x74\x7e"          /* mov si, offset message */ \
  42                                         /* write_msg_loop: */           \
  43                         "\xac"                  /* lodsb */             \
  44                         "\x22\xc0"              /* and al, al */        \
  45                         "\x74\x06"              /* jz done (+8) */      \
  46                         "\xb4\x0e"              /* mov ah, 0x0e */      \
  47                         "\xcd\x10"              /* int 0x10 */          \
  48                         "\xeb\xf5"              /* jmp write_msg_loop */ \
  49                                         /* done: */                     \
  50                         "\xb4\x00"              /* mov ah, 0x00 */      \
  51                         "\xcd\x16"              /* int 0x16 */          \
  52                         "\xb4\x00"              /* mov ah, 0x00 */      \
  53                         "\xcd\x19"              /* int 0x19 */          \
  54                         "\xeb\xfe"              /* jmp +0 - in case int 0x19 */ \
  55                                                 /* doesn't work */      \
  56                                         /* message: */                  \
  57                         FAT_BOOT_MESSAGE
  58 
  59 #define FAT_BOOT_CODE_LENGTH 128
  60 
  61 #ifdef __sun
  62 #define __attribute__(X)        /*nothing*/
  63 #endif /* __sun */
  64 
  65 #ifdef __sun
  66 #pragma pack(1)
  67 #endif
  68 struct __attribute__ ((packed)) _FatBootSector {
  69         uint8_t         boot_jump[3];   /* 00: Boot strap short or near jump */
  70         uint8_t         system_id[8];   /* 03: system name */
  71         uint16_t        sector_size;    /* 0b: bytes per logical sector */
  72         uint8_t         cluster_size;   /* 0d: sectors/cluster */
  73         uint16_t        reserved;       /* 0e: reserved sectors */
  74         uint8_t         fats;           /* 10: number of FATs */
  75         uint16_t        dir_entries;    /* 11: number of root directory entries */
  76         uint16_t        sectors;        /* 13: if 0, total_sect supersedes */
  77         uint8_t         media;          /* 15: media code */
  78         uint16_t        fat_length;     /* 16: sectors/FAT for FAT12/16 */
  79         uint16_t        secs_track;     /* 18: sectors per track */
  80         uint16_t        heads;          /* 1a: number of heads */
  81         uint32_t        hidden;         /* 1c: hidden sectors (partition start) */
  82         uint32_t        sector_count;   /* 20: no. of sectors (if sectors == 0) */
  83 
  84         union __attribute__ ((packed)) {
  85                 /* FAT16 fields */
  86                 struct __attribute__ ((packed)) {
  87                         uint8_t         drive_num;      /* 24: */
  88                         uint8_t         empty_1;        /* 25: */
  89                         uint8_t         ext_signature;  /* 26: always 0x29 */
  90                         uint32_t        serial_number;  /* 27: */
  91                         uint8_t         volume_name [11];       /* 2b: */
  92                         uint8_t         fat_name [8];   /* 36: */
  93                         uint8_t         boot_code[448]; /* 3f: Boot code (or message) */
  94                 } fat16;
  95                 /* FAT32 fields */
  96                 struct __attribute__ ((packed)) {
  97                         uint32_t        fat_length;     /* 24: size of FAT in sectors */
  98                         uint16_t        flags;          /* 28: bit8: fat mirroring, low4: active fat */
  99                         uint16_t        version;        /* 2a: minor * 256 + major */
 100                         uint32_t        root_dir_cluster;       /* 2c: */
 101                         uint16_t        info_sector;    /* 30: */
 102                         uint16_t        backup_sector;  /* 32: */
 103                         uint8_t         empty_1 [12];   /* 34: */
 104                         uint16_t        drive_num;      /* 40: */
 105                         uint8_t         ext_signature;  /* 42: always 0x29 */
 106                         uint32_t        serial_number;  /* 43: */
 107                         uint8_t         volume_name [11];       /* 47: */
 108                         uint8_t         fat_name [8];   /* 52: */
 109                         uint8_t         boot_code[420]; /* 5a: Boot code (or message) */
 110                 } fat32;
 111         } u;
 112 
 113         uint16_t        boot_sign;      /* 1fe: always 0xAA55 */
 114 };
 115 
 116 struct __attribute__ ((packed)) _FatInfoSector {
 117         uint32_t        signature_1;    /* should be 0x41615252 */
 118         uint8_t         unused [480];
 119         uint32_t        signature_2;    /* should be 0x61417272 */
 120         uint32_t        free_clusters;
 121         uint32_t        next_cluster;   /* most recently allocated cluster */
 122         uint8_t         unused2 [0xe];
 123         uint16_t        signature_3;    /* should be 0xaa55 */
 124 };
 125 #ifdef __sun
 126 #pragma pack()
 127 #endif
 128 
 129 int fat_boot_sector_read (FatBootSector* bs, const PedGeometry* geom);
 130 FatType fat_boot_sector_probe_type (const FatBootSector* bs,
 131                                     const PedGeometry* geom);
 132 int fat_boot_sector_analyse (FatBootSector* bs, PedFileSystem* fs);
 133 int fat_boot_sector_set_boot_code (FatBootSector* bs);
 134 int fat_boot_sector_generate (FatBootSector* bs, const PedFileSystem* fs);
 135 int fat_boot_sector_write (const FatBootSector* bs, PedFileSystem* fs);
 136 
 137 int fat_info_sector_read (FatInfoSector* is, const PedFileSystem* fs);
 138 int fat_info_sector_generate (FatInfoSector* is, const PedFileSystem* fs);
 139 int fat_info_sector_write (const FatInfoSector* is, PedFileSystem* fs);
 140 
 141 #endif /* PED_FAT_BOOTSECTOR_H */
 142