📄 dos.c
字号:
} /* parse the data for real */ nexttablebase = 0; for (i = 0; i < 4; i++) { start = starts[i]; size = sizes[i]; type = types[i]; if (size == 0) continue; if (type == 0x05 || type == 0x85) { /* inner extended partition */ nexttablebase = extbase + start; } else { /* logical partition */ info->partmap.part_type = type; info->partmap.part_type_name = get_name_for_type(type); info->partmap.start = start; info->partmap.size = size * 512; info->partmap.num = *extpartnum; /* sprintf(append, " from %llu+%lu", tablebase, start); format_blocky_size(s, size, 512, "sectors", append); print_line(level, "Partition %d: %s", *extpartnum, s); */ (*extpartnum)++; /* print_line(level + 1, "Type 0x%02X (%s)", type, get_name_for_type(type)); */ /* recurse for content detection */ rs.source = section->source; rs.pos = section->pos + (tablebase + start) * 512; rs.size = (U64)size * 512; rs.flags = 0; info->next = dt_detect(&rs); } } } if(info->partmap.part_type != 0) return DT_YES; return DT_NO;}/* * FAT12/FAT16/FAT32 file systems */static char *fatnames[] = { "FAT12", "FAT16", "FAT32" };int detect_fat(SECTION *section, DT_Info* info) { int i, score, fattype; U32 sectsize, clustersize, reserved, fatcount, dirsize, fatsize; U64 sectcount, clustercount; U16 atari_csum; unsigned char *buf; char s[256]; if (get_buffer(section, 0, 512, (void **)&buf) < 512) return DT_NO; /* first, some hard tests */ /* sector size has four allowed values */ sectsize = get_le_short(buf + 11); if (sectsize != 512 && sectsize != 1024 && sectsize != 2048 && sectsize != 4096) return DT_NO; /* sectors per cluster: must be a power of two */ clustersize = buf[13]; if (clustersize == 0 || (clustersize & (clustersize - 1))) return DT_NO; /* since the above is also present on NTFS, make sure it's not NTFS... */ if (memcmp(buf + 3, "NTFS ", 8) == 0) return DT_NO; /* next, some soft tests, taking score */ score = 0; /* boot jump */ if ((buf[0] == 0xEB && buf[2] == 0x90) || buf[0] == 0xE9) score++; /* boot signature */ if (buf[510] == 0x55 && buf[511] == 0xAA) score++; /* reserved sectors */ reserved = get_le_short(buf + 14); if (reserved == 1 || reserved == 32) score++; /* number of FATs */ fatcount = buf[16]; if (fatcount == 2) score++; /* number of root dir entries */ dirsize = get_le_short(buf + 17); /* sector count (16-bit and 32-bit versions) */ sectcount = get_le_short(buf + 19); if (sectcount == 0) sectcount = get_le_long(buf + 32); /* media byte */ if (buf[21] == 0xF0 || buf[21] >= 0xF8) score++; /* FAT size in sectors */ fatsize = get_le_short(buf + 22); if (fatsize == 0) fatsize = get_le_long(buf + 36); /* determine FAT type */ dirsize = ((dirsize * 32) + (sectsize - 1)) / sectsize; clustercount = sectcount - (reserved + (fatcount * fatsize) + dirsize); clustercount /= clustersize; if (clustercount < 4085) { fattype = 0; info->fs.type_version = 12; } else if (clustercount < 65525) { fattype = 1; info->fs.type_version = 16; } else { fattype = 2; info->fs.type_version = 32; } /* check for ATARI ST boot checksum */ atari_csum = 0; for (i = 0; i < 512; i += 2) atari_csum += get_be_short(buf + i); /* tell the user */ s[0] = 0; if (atari_csum == 0x1234) strcpy(s, _T(", ATARI ST bootable")); info->fs.type = DT_FAT; info->fs.type_version_name = strdup(fatnames[fattype]); /* TODO: include Atari boot msg and hints score */ info->fs.type_name = strdup("vfat"); /* print_line(level, "%s file system +(hints score %d of %d%s)", fatnames[fattype], score, 5, s); */ info->fs.volume_blocksize = clustercount; info->fs.volume_blocks = clustersize * sectsize; info->fs.volume_size = clustercount * clustersize * sectsize; /* if (sectsize > 512) print_line(level + 1, "Unusual sector size %lu bytes", sectsize); format_blocky_size(s, clustercount, clustersize * sectsize, "clusters", NULL); print_line(level + 1, "Volume size %s", s); */ /* get the cached volume name if present */ if (fattype < 2) { if (buf[38] == 0x29) { memcpy(s, buf + 43, 11); s[11] = 0; for (i = 10; i >= 0 && s[i] == ' '; i--) s[i] = 0; if (strcmp(s, "NO NAME") != 0) { info->fs.volume_name = strdup(s); /* print_line(level + 1, "Volume name \"%s\"", s); */ } } } else { if (buf[66] == 0x29) { memcpy(s, buf + 71, 11); s[11] = 0; for (i = 10; i >= 0 && s[i] == ' '; i--) s[i] = 0; if (strcmp(s, "NO NAME") != 0) { info->fs.volume_name = strdup(s); /* print_line(level + 1, "Volume name \"%s\"", s); */ } } } /* TODO: */ /* Is this a good assumption ?? */ if(score > 3) return DT_YES; return DT_NO;}/* * NTFS file system */int detect_ntfs(SECTION *section, DT_Info* info) { U32 sectsize, clustersize; U64 sectcount; unsigned char *buf; if (get_buffer(section, 0, 512, (void **)&buf) < 512) return DT_NO; /* check signatures */ if (memcmp(buf + 3, "NTFS ", 8) != 0) return DT_NO; /* disabled for now, mkntfs(8) doesn't generate it if (memcmp(buf + 0x24, "\0x80\0x00\0x80\0x00", 4) != 0) return; */ /* sector size: must be a power of two */ sectsize = get_le_short(buf + 11); if (sectsize < 512 || (sectsize & (sectsize - 1))) return DT_NO; /* sectors per cluster: must be a power of two */ clustersize = buf[13]; if (clustersize == 0 || (clustersize & (clustersize - 1))) return DT_NO; /* get size in sectors */ sectcount = get_le_quad(buf + 0x28); /* tell the user */ info->fs.type = DT_NTFS; info->fs.type_version_name = _T("NTFS file system"); info->fs.type_name = strdup("ntfs"); info->fs.volume_size = sectcount * sectsize; info->fs.volume_blocks = sectcount; info->fs.volume_blocksize = sectsize; /* print_line(level, "NTFS file system"); format_blocky_size(s, sectcount, sectsize, "sectors", NULL); print_line(level + 1, "Volume size %s", s); */ return DT_YES;}/* * HPFS file system */int detect_hpfs(SECTION *section, DT_Info* info) { unsigned char *buf; U64 sectcount; if (get_buffer(section, 16*512, 512, (void **)&buf) < 512) return DT_NO; if (memcmp(buf, "\0xF9\0x95\0xE8\0x49\0xFA\0x53\0xE9\0xC5", 8) != 0) return DT_NO; info->fs.type = DT_HPFS; info->fs.type_version = (int)buf[8]; info->fs.type_subversion = (int)buf[9]; info->fs.type_version_name = _T("HPFS file system"); info->fs.type_name = strdup("hpfs"); /* print_line(level, "HPFS file system (version %d, functional version %d)", (int)buf[8], (int)buf[9]); */ sectcount = get_le_long(buf + 16); info->fs.volume_blocks = sectcount; info->fs.volume_blocksize = 512; info->fs.volume_size = 512 * sectcount; /* format_blocky_size(s, sectcount, 512, "sectors", NULL); print_line(level + 1, "Volume size %s", s); */ /* TODO: BPB in boot sector, volume label -- information? */ return DT_YES;}/* EOF */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -