📄 atari.c
字号:
/* * atari.c * Detection of ATARI ST partition map * * Copyright (c) 2003 Christoph Pfisterer * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, * modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */#include "detect.h"/* * ATARI ST partition map */static char * get_name_for_type(char *type) { if (memcmp(type, "GEM", 3) == 0) return "Standard GEMDOS"; else if (memcmp(type, "BGM", 3) == 0) return "Big GEMDOS"; else if (memcmp(type, "XGM", 3) == 0) return "Extended"; return "Unknown";}static void detect_atari_partmap_ext(SECTION *section, U64 extbase, int level);void detect_atari_partmap(SECTION *section, int level) { unsigned char *buf; int i, off, used, flag, flags[4]; U32 start, size, starts[4], sizes[4]; char types[4][4], *type; U16 atari_csum; char s[256], append[64]; /* partition maps only occur at the start of a device */ if (section->pos != 0) return; if (get_buffer(section, 0, 512, (void **)&buf) < 512) return; /* check checksum */ atari_csum = 0; for (i = 0; i < 512; i += 2) atari_csum += get_be_short(buf + i); if (atari_csum != 0x1234) return; /* get data and check if it's actually used */ used = 0; for (off = 0x1c6, i = 0; i < 4; i++, off += 12) { flags[i] = buf[off]; get_string(buf + off + 1, 3, types[i]); starts[i] = get_be_long(buf + off + 4); sizes[i] = get_be_long(buf + off + 8); if ((flags[i] & 1) && starts[i] != 0 && sizes[i] != 0) used = 1; } if (!used) return; /* print data and handle each partition */ print_line(level, "ATARI ST partition map"); for (i = 0; i < 4; i++) { start = starts[i]; size = sizes[i]; flag = flags[i]; type = types[i]; if ((flag & 1) == 0) continue; sprintf(append, " from %lu", start); if (flag & 0x80) strcat(append, ", bootable"); format_blocky_size(s, size, 512, "sectors", append); print_line(level, "Partition %d: %s", i+1, s); print_line(level + 1, "Type \"%s\" (%s)", type, get_name_for_type(type)); if (memcmp(type, "XGM", 3) == 0) { /* extended partition */ detect_atari_partmap_ext(section, start, level + 1); } else { /* recurse for content detection */ analyze_recursive(section, level + 1, (U64)start * 512, (U64)size * 512, 0); } }}static void detect_atari_partmap_ext(SECTION *section, U64 extbase, int level) { unsigned char *buf; int extpartnum = 5; U64 tablebase, nexttablebase; int i, off, flags[4]; U32 start, size, starts[4], sizes[4]; char types[4][4], *type; char s[256], append[64]; for (tablebase = extbase; tablebase; tablebase = nexttablebase) { /* read sector from linked list */ if (get_buffer(section, tablebase << 9, 512, (void **)&buf) < 512) return; /* get data */ for (off = 0x1c6, i = 0; i < 4; i++, off += 12) { flags[i] = buf[off]; get_string(buf + off + 1, 3, types[i]); starts[i] = get_be_long(buf + off + 4); sizes[i] = get_be_long(buf + off + 8); } /* print data and handle each partition */ nexttablebase = 0; for (i = 0; i < 4; i++) { start = starts[i]; size = sizes[i]; type = types[i]; if ((flags[i] & 1) == 0) continue; if (memcmp(type, "XGM", 3) == 0) { /* link to next table */ nexttablebase = extbase + start; } else { /* real partition */ sprintf(append, " from %lu", start); format_blocky_size(s, size, 512, "sectors", append); print_line(level, "Partition %d: %s", extpartnum, s); extpartnum++; print_line(level + 1, "Type \"%s\" (%s)", type, get_name_for_type(type)); /* recurse for content detection */ analyze_recursive(section, level + 1, (tablebase + start) * 512, (U64)size * 512, 0); } } }}/* EOF */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -