FreeCalypso > hg > freecalypso-reveng
view miscprog/grokdsn.c @ 191:0c631396b8ce
started grokdsn utility, parses header successfully
author | Michael Spacefalcon <falcon@ivan.Harhan.ORG> |
---|---|
date | Wed, 07 Jan 2015 06:55:33 +0000 |
parents | |
children | 5d84f63eff72 |
line wrap: on
line source
/* * We have TI's Leonardo reference schematics in the form of 3 different PDF * versions and an OrCAD DSN file corresponding to one of them. The latter * appears (based on a cursory strings(1) inspection) to contain more * juicy information than is present in the PDF prints. We need to extract * as much of this information as we can in order to replicate the lost * Leonardo board as closely as possible. * * The top level structure of this DSN file appears to be Microsoft CDF. * Therefore, I shall begin by parsing this "archive" structure and * extracting the individual files contained therein, in an effort to gain * more insight as to what goes with what than can be gleaned from strings(1) * on the raw DSN file. This hack-utility is my CDF parser written for * this specific purpose. */ #include <sys/types.h> #include <sys/file.h> #include <sys/stat.h> #include <sys/mman.h> #include <stdio.h> #include <stdint.h> #include <endian.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <strings.h> #define HEADER_MFAT_ENTRIES 109 struct cdf_header { u_char magic[8]; u_char uid[16]; uint16_t fmt_minor; uint16_t fmt_major; uint16_t byte_order; uint16_t sector_size; uint16_t subsec_size; u_char rsvd1[10]; uint32_t fat_sectors; uint32_t dir_start; u_char rsvd2[4]; uint32_t min_large_file; uint32_t subfat_start; uint32_t subfat_sectors; uint32_t mfat_start; uint32_t mfat_sectors; uint32_t fat_secids[HEADER_MFAT_ENTRIES]; }; char *dsnfilename; u_char *filemapping; struct cdf_header *cdf_header; unsigned total_sectors; open_and_mmap_file() { int fd; struct stat st; fd = open(dsnfilename, O_RDONLY); if (fd < 0) { perror(dsnfilename); exit(1); } fstat(fd, &st); if (!S_ISREG(st.st_mode)) { fprintf(stderr, "error: %s is not a regular file\n", dsnfilename); exit(1); } if (st.st_size < 512) { fprintf(stderr, "error: %s is shorter than 512 bytes\n", dsnfilename); exit(1); } if (st.st_size % 512) { fprintf(stderr, "error: %s is not a multiple of 512 bytes\n", dsnfilename); exit(1); } filemapping = mmap(0, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); if (filemapping == MAP_FAILED) { perror("mmap"); exit(1); } close(fd); cdf_header = (struct cdf_header *) filemapping; total_sectors = st.st_size / 512 - 1; return(0); } dump_cdf_header() { printf("Magic: %02X %02X %02X %02X %02X %02X %02X %02X\n", cdf_header->magic[0], cdf_header->magic[1], cdf_header->magic[2], cdf_header->magic[3], cdf_header->magic[4], cdf_header->magic[5], cdf_header->magic[6], cdf_header->magic[7]); printf("Format version: %04X.%04X\n", le16toh(cdf_header->fmt_major), le16toh(cdf_header->fmt_minor)); printf("Sector / subsector shift: %u / %u\n", le16toh(cdf_header->sector_size), le16toh(cdf_header->subsec_size)); printf("Total FAT sectors: %u\n", le32toh(cdf_header->fat_sectors)); printf("Directory start sector: %u\n", le32toh(cdf_header->dir_start)); printf("File size threshold: %u\n", le32toh(cdf_header->min_large_file)); return(0); } main(argc, argv) char **argv; { if (sizeof(struct cdf_header) != 512) { fprintf(stderr, "error: struct cdf_header is misdefined\n"); exit(1); } if (argc != 3) { fprintf(stderr, "usage: %s binfile.dsn <operation>\n", argv[0]); exit(1); } dsnfilename = argv[1]; open_and_mmap_file(); if (!strcmp(argv[2], "hdr")) return dump_cdf_header(); fprintf(stderr, "error: \"%s\" is not a recognized command\n", argv[2]); exit(1); }