comparison 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
comparison
equal deleted inserted replaced
190:6b9668541965 191:0c631396b8ce
1 /*
2 * We have TI's Leonardo reference schematics in the form of 3 different PDF
3 * versions and an OrCAD DSN file corresponding to one of them. The latter
4 * appears (based on a cursory strings(1) inspection) to contain more
5 * juicy information than is present in the PDF prints. We need to extract
6 * as much of this information as we can in order to replicate the lost
7 * Leonardo board as closely as possible.
8 *
9 * The top level structure of this DSN file appears to be Microsoft CDF.
10 * Therefore, I shall begin by parsing this "archive" structure and
11 * extracting the individual files contained therein, in an effort to gain
12 * more insight as to what goes with what than can be gleaned from strings(1)
13 * on the raw DSN file. This hack-utility is my CDF parser written for
14 * this specific purpose.
15 */
16
17 #include <sys/types.h>
18 #include <sys/file.h>
19 #include <sys/stat.h>
20 #include <sys/mman.h>
21 #include <stdio.h>
22 #include <stdint.h>
23 #include <endian.h>
24 #include <stdlib.h>
25 #include <unistd.h>
26 #include <string.h>
27 #include <strings.h>
28
29 #define HEADER_MFAT_ENTRIES 109
30 struct cdf_header {
31 u_char magic[8];
32 u_char uid[16];
33 uint16_t fmt_minor;
34 uint16_t fmt_major;
35 uint16_t byte_order;
36 uint16_t sector_size;
37 uint16_t subsec_size;
38 u_char rsvd1[10];
39 uint32_t fat_sectors;
40 uint32_t dir_start;
41 u_char rsvd2[4];
42 uint32_t min_large_file;
43 uint32_t subfat_start;
44 uint32_t subfat_sectors;
45 uint32_t mfat_start;
46 uint32_t mfat_sectors;
47 uint32_t fat_secids[HEADER_MFAT_ENTRIES];
48 };
49
50 char *dsnfilename;
51 u_char *filemapping;
52 struct cdf_header *cdf_header;
53 unsigned total_sectors;
54
55 open_and_mmap_file()
56 {
57 int fd;
58 struct stat st;
59
60 fd = open(dsnfilename, O_RDONLY);
61 if (fd < 0) {
62 perror(dsnfilename);
63 exit(1);
64 }
65 fstat(fd, &st);
66 if (!S_ISREG(st.st_mode)) {
67 fprintf(stderr, "error: %s is not a regular file\n",
68 dsnfilename);
69 exit(1);
70 }
71 if (st.st_size < 512) {
72 fprintf(stderr, "error: %s is shorter than 512 bytes\n",
73 dsnfilename);
74 exit(1);
75 }
76 if (st.st_size % 512) {
77 fprintf(stderr, "error: %s is not a multiple of 512 bytes\n",
78 dsnfilename);
79 exit(1);
80 }
81 filemapping = mmap(0, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
82 if (filemapping == MAP_FAILED) {
83 perror("mmap");
84 exit(1);
85 }
86 close(fd);
87 cdf_header = (struct cdf_header *) filemapping;
88 total_sectors = st.st_size / 512 - 1;
89 return(0);
90 }
91
92 dump_cdf_header()
93 {
94 printf("Magic: %02X %02X %02X %02X %02X %02X %02X %02X\n",
95 cdf_header->magic[0], cdf_header->magic[1],
96 cdf_header->magic[2], cdf_header->magic[3],
97 cdf_header->magic[4], cdf_header->magic[5],
98 cdf_header->magic[6], cdf_header->magic[7]);
99 printf("Format version: %04X.%04X\n", le16toh(cdf_header->fmt_major),
100 le16toh(cdf_header->fmt_minor));
101 printf("Sector / subsector shift: %u / %u\n",
102 le16toh(cdf_header->sector_size),
103 le16toh(cdf_header->subsec_size));
104 printf("Total FAT sectors: %u\n", le32toh(cdf_header->fat_sectors));
105 printf("Directory start sector: %u\n", le32toh(cdf_header->dir_start));
106 printf("File size threshold: %u\n",
107 le32toh(cdf_header->min_large_file));
108 return(0);
109 }
110
111 main(argc, argv)
112 char **argv;
113 {
114 if (sizeof(struct cdf_header) != 512) {
115 fprintf(stderr, "error: struct cdf_header is misdefined\n");
116 exit(1);
117 }
118 if (argc != 3) {
119 fprintf(stderr, "usage: %s binfile.dsn <operation>\n", argv[0]);
120 exit(1);
121 }
122 dsnfilename = argv[1];
123 open_and_mmap_file();
124 if (!strcmp(argv[2], "hdr"))
125 return dump_cdf_header();
126 fprintf(stderr, "error: \"%s\" is not a recognized command\n", argv[2]);
127 exit(1);
128 }