⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fat.c

📁 fat_repair程序
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <unistd.h>#include <fcntl.h>#include <string.h>#include <errno.h>#include <inttypes.h>#include <malloc.h>#define STDIN 0#define STDOUT 1#define STDERR 2#define SECTOR_SIZE 512#define MAX(a,b) ((a<b)?(b):(a))#define die(a) _die(__FUNCTION__, __LINE__, a)#define ATTR_READ_ONLY 0x01#define ATTR_HIDDEN    0x02#define ATTR_SYSTEM    0x04#define ATTR_VOLUME_ID 0x08#define ATTR_DIRECTORY 0x10#define ATTR_ARCHIVE   0x20#define ATTR_LONG_NAME (ATTR_READ_ONLY | ATTR_HIDDEN | ATTR_SYSTEM | \  ATTR_VOLUME_ID)#define ATTR_LONG_NAME_MASK (ATTR_READ_ONLY | ATTR_HIDDEN | ATTR_SYSTEM | \  ATTR_VOLUME_ID | ATTR_DIRECTORY | ATTR_ARCHIVE)int err = 0;enum Fattype {  FATunknown,  FAT12,  FAT16,  FAT32};struct Bpb {  uint8_t  BS_jmpBoot[3];    /* jump instruction to boot code */  uint8_t  BS_OEMName[8];    /* "MSWIN4.1" */  uint16_t BPB_BytsPerSec;   /* bytes per sector (512, 1k, 2k, 4k) */  uint8_t  BPB_SecPerClus;   /* sectors per cluster (2^n, 0<=n<=7) */  uint16_t BPB_RsvdSecCnt;   /* number of reserved sectors */  uint8_t  BPB_NumFATs;      /* count of FATs on the volume (usually 2) */  uint16_t BPB_RootEntCnt;   /* count of root directory entries (0 if FAT32) */  uint16_t BPB_TotSec16;     /* total count of sectors (0 if FAT32) */  uint8_t  BPB_Media;        /* media type, usally 0xf8 */  uint16_t BPB_FATSz16;      /* sectors occupied by one fat (FAT12 / FAT16) */  uint16_t BPB_SecPerTrk;    /* sectors per track for Int 0x13 */  uint16_t BPB_NumHeads;     /* numbers of heads for Int 0x13 */  uint32_t BPB_HiddSec;      /* count of sectors preceding the partition */  uint32_t BPB_TotSec32;     /* total count of all sectors of the volume */} __attribute__ ((packed));struct Bpb16 {  uint8_t  BS_DrvNum;        /* Int 0x13 drive number, eg. 0x80 */  uint8_t  BS_Reserved1;     /* reserved for WinNT (usually 0) */  uint8_t  BS_BootSig;       /* extended boot signature (0x29) */  uint32_t BS_VolID;         /* volume serial number (date + time) */  uint8_t  BS_VolLab[11];    /* volume label as stored in the root directory */  uint8_t  BS_FilSysType[8]; /* informational! */} __attribute__ ((packed));struct Bpb32 {  uint32_t BPB_FATSz32;      /* sectors occupied by one fat (FAT32) */  uint16_t BPB_ExtFlags;     /* FAT mirrored? */  uint16_t BPB_FSVer;        /* version number of FAT filesystem type */  uint32_t BPB_RootClus;     /* cluster number of first cluster of root dir */  uint16_t BPB_FSInfo;       /* sector number of FSINFO (usually 1) */  uint16_t BPB_BkBootSec;    /* sector number of copy of boot sector */  uint8_t  BPB_Reserved[12]; /* reserved for future use */  uint8_t  BS_DrvNum;        /* Int 0x13 drive number, eg. 0x80 */  uint8_t  BS_Reserved1;     /* reserved for WinNT (usually 0) */  uint8_t  BS_BootSig;       /* extended boot signature (0x29) */  uint32_t BS_VolID;         /* volume serial number (date + time) */  uint8_t  BS_VolLab[11];    /* volume label as stored in the root directory */  uint8_t  BS_FilSysType[8]; /* informational! */} __attribute__ ((packed));struct Dirent {  uint8_t  DIR_Name[11];  uint8_t  DIR_Attr;  uint8_t  DIR_NTRes;  uint8_t  DIR_CrtTimeTenth;  uint16_t DIR_CrtTime;  uint16_t DIR_CrtDate;  uint16_t DIR_LstAccDate;  uint16_t DIR_FstClusHI;  uint16_t DIR_WrtTime;  uint16_t DIR_WrtDate;  uint16_t DIR_FstClusLO;  uint32_t DIR_FileSize;} __attribute__ ((packed));struct Ldirent {  uint8_t  LDIR_Ord;  uint8_t  LDIR_Name1[10];  uint8_t  LDIR_Attr;  uint8_t  LDIR_Type;  uint8_t  LDIR_Chksum;  uint8_t  LDIR_Name2[12];  uint16_t LDIR_FstClusLO;  uint8_t  LDIR_Name3[4];} __attribute__ ((packed));void _write (int fd, char *msg){  if (msg) write(fd, msg, strlen(msg));  else write(fd, "[null]", 6);}void write1 (char *msg){  if (msg) _write(STDOUT, msg);}void write2 (char *msg){  if (msg) _write(STDERR, msg);}char *ultoa (uint64_t i){  static char ret[4096];  static uint64_t itmp;  static int len;  len = 0;  itmp = i;  do {    ++len;    itmp /= 10;  } while (itmp);  ret[len] = '\0';  for (;;) {    ret[--len] = '0' + i % 10;    i /= 10;    if (!len) break;  }  return &ret[0];}void _die (char *func, int line, char *why){  write2(func);  write2(" (");  write2(ultoa(line));  write2("): ");  write2(why);  write2(".\n");  exit(1);}void warn (char *warning){  ++err;  write1("warning: ");  write1(warning);  write1(".\n");}void fatal (char *warning){  ++err;  write1("Fatal: ");  write1(warning);  write1(".\n");}enum Fattype guess_fattype (struct Bpb *bpb, struct Bpb16 *bpb16,                            struct Bpb32 *bpb32){  uint64_t clusters, rootdirsectors;  uint32_t totalsectors, fatsize;  enum Fattype fat = FAT32;  write1("=== guessing FAT type ===\nHmm, looks like a ");  totalsectors = ((bpb->BPB_TotSec16)?(bpb->BPB_TotSec16):(bpb->BPB_TotSec32));  fatsize = ((bpb->BPB_FATSz16)?(bpb->BPB_FATSz16):(bpb32->BPB_FATSz32));  rootdirsectors = (bpb->BPB_RootEntCnt * 32 + bpb->BPB_BytsPerSec - 1) / \                   bpb->BPB_BytsPerSec;  clusters = (totalsectors - bpb->BPB_RsvdSecCnt - bpb->BPB_NumFATs * fatsize -\              rootdirsectors) / bpb->BPB_SecPerClus;  if (clusters < 4085) fat = FAT12;  if (clusters < 65525) fat = FAT16;entry:  err = 0;  switch (fat) {    case FATunknown:    case FAT32:      write1("FAT32\n");      if (bpb->BPB_RootEntCnt)       warn("BPB_RootEntCnt non zero");      if (bpb->BPB_TotSec16)         warn("BPB_TotSec16 non zero");      if (bpb->BPB_FATSz16)          warn("BPB_FATSz16 non zero");      if (!bpb->BPB_TotSec32)        warn("BPB_TotSec32 zero");      if (!bpb32->BPB_FATSz32)       warn("BPB_FATSz32 zero");      if (bpb32->BPB_FSVer)          warn("BPB_FSVer non zero");      if (bpb32->BPB_RootClus != 2)  warn("BPB_RootClus not 2");      if (bpb32->BPB_FSInfo != 1)    warn("BPB_FSInfo not 1");      if (bpb32->BPB_BkBootSec != 6) warn("BPB_BkBootSec not 6");      if (bpb32->BS_Reserved1)       warn("BS_Reserved1 non zero");      write1("BS_VolLab: "); write(STDOUT, bpb32->BS_VolLab, 11); write1("\n");      if (memcmp(&bpb32->BS_FilSysType[0], "FAT32   ", 8))        warn("BS_FilSysType not \"FAT32   \"");      if (err) {        warn("Too many errors on this FAT32 volume, trying again");        if (fat != FATunknown) {          fat = FATunknown;          goto entry;        }      }      if (fat != FATunknown) break;    case FAT16:      write1("FAT16\n");      if (bpb->BPB_RsvdSecCnt != 1) warn("BPB_RsvdSecCnt not 1");      if (!bpb->BPB_RootEntCnt)     warn("BPB_RootEntCnt zero");      if (!bpb->BPB_FATSz16)        warn("BPB_FATSz16 zero");      if (bpb16->BS_Reserved1)      warn("BS_Reserved1 non zero");      write1("BS_VolLab: "); write(STDOUT, bpb16->BS_VolLab, 11); write1("\n");      if (memcmp(&bpb16->BS_FilSysType[0], "FAT16 ", 8))        warn("BS_FilSysType not \"FAT16   \"");      if (err) {        warn("Too many errors on this FAT16 volume, trying again");        if (fat != FATunknown) {          fat = FATunknown;          goto entry;        }      }      if (fat != FATunknown) break;    case FAT12:      write1("FAT12\n");      if (bpb->BPB_RsvdSecCnt != 1) warn("BPB_RsvdSecCnt not 1");      if (!bpb->BPB_RootEntCnt)     warn("BPB_RootEntCnt zero");      if (!bpb->BPB_FATSz16)        warn("BPB_FATSz16 zero");      if (bpb16->BS_Reserved1)      warn("BS_Reserved1 non zero");      write1("BS_VolLab: "); write(STDOUT, bpb16->BS_VolLab, 11); write1("\n");      if (memcmp(&bpb16->BS_FilSysType[0], "FAT12 ", 8))        warn("BS_FilSysType not \"FAT12   \"");      if (err) {        warn("Too many errors on this FAT12 volume, trying again");        if (fat != FATunknown) {          fat = FATunknown;          goto entry;        }      }      if (fat != FATunknown) break;      die("Could not determine FAT type");  }  write1("looks fine\n");  return fat;}void dumpbpb (struct Bpb *bpb, struct Bpb16 *bpb16, struct Bpb32 *bpb32,              enum Fattype fat){  if (!bpb) die("bpb = NULL");  if (!bpb16) die("bpb16 = NULL");  if (!bpb32) die("bpb32 = NULL");  write1("=== dumping ===\n");  write1("BS_jmpBoot: ");     write1(ultoa((uint32_t)(bpb->BS_jmpBoot[0] << 16) + \                         (bpb->BS_jmpBoot[1] << 8) + \                          bpb->BS_jmpBoot[2]));  write1("\nBS_OEMName: ");  write(STDOUT, &bpb->BS_OEMName[0], 8);  write1("\nBPB_BytsPerSec: ");  write1(ultoa(bpb->BPB_BytsPerSec));  write1("\nBPB_SecPerClus: ");  write1(ultoa(bpb->BPB_SecPerClus));  write1("\nBPB_RsvdSecCnt: ");  write1(ultoa(bpb->BPB_RsvdSecCnt));  write1("\nBPB_NumFATs: ");  write1(ultoa(bpb->BPB_NumFATs));  write1("\nBPB_RootEntCnt: ");  write1(ultoa(bpb->BPB_RootEntCnt));  write1("\nBPB_TotSec16: ");  write1(ultoa(bpb->BPB_TotSec16));  write1("\nBPB_Media: ");  write1(ultoa(bpb->BPB_Media));  write1("\nBPB_FATSz16: ");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -