From 914508121b223930139c4f7beb14a252ca84c0f1 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Sun, 28 Jun 2020 04:28:32 +0000 Subject: [PATCH] progress... --- dump-float.c | 2 +- dump-spo2.c | 320 +++++++++++++++++++++++++++++++++++++++------------ spo-notes | 3 +- 3 files changed, 249 insertions(+), 76 deletions(-) diff --git a/dump-float.c b/dump-float.c index 4f41280f00..718d2a113b 100644 --- a/dump-float.c +++ b/dump-float.c @@ -21,7 +21,7 @@ print_float (const uint8_t *b) int main (void) { - uint8_t b[] = { 0, 0, 0, 0, 0, 0x49, 0xd2, 0x40 }; + uint8_t b[] = { 0xc3, 0xe2, 0xb7, 0xc2, 0xb0, 0xe1, 0xb0, 0xfa }; int n = sizeof b; for (int i = 0; i <= n - 8; i++) print_double (b + i); diff --git a/dump-spo2.c b/dump-spo2.c index 06b3902e3e..bc1e97d57f 100644 --- a/dump-spo2.c +++ b/dump-spo2.c @@ -25,6 +25,9 @@ unsigned int pos; #define STR(x) XSTR(x) #define WHERE __FILE__":" STR(__LINE__) +static void __attribute__((unused)) +hex_dump(FILE *stream, int ofs, int n); + static uint8_t get_byte(void) { @@ -186,7 +189,8 @@ match_byte_assert(uint8_t b, const char *where) { if (!match_byte(b)) { - fprintf(stderr, "%s: 0x%x: expected %02x, got %02x\n", where, pos, b, data[pos]); + fprintf(stderr, "%s: 0x%x: expected %02x, got %02x: ", where, pos, b, data[pos]); + hex_dump(stderr, pos, 64); exit(1); } } @@ -474,8 +478,9 @@ match_zeros_assert(int count, const char *where) if (data[pos + i]) { fprintf (stderr, - "%s: %#x: expected %d zeros here but offset %d is %#"PRIx8"\n", + "%s: %#x: expected %d zeros here but offset %d is %#"PRIx8": ", where, pos, count, i, data[pos + i]); + hex_dump (stderr, pos, 64); exit (1); } pos += count; @@ -499,18 +504,20 @@ put_safe(const char *s) } } +static void parse_flexible(void); + static void parse_DspString(void) { + printf("%#x: DspString(", pos); if (match_byte(2)) { - printf("DspString(%f, \"", get_double()); + printf("%f, \"", get_double()); printf("%s\")\n", get_string1()); } else { match_byte_assert(1); - printf ("DspString("); parse_format(); printf(" \""); match_byte_assert(0); @@ -533,10 +540,28 @@ match_DspSimpleText(void) { /* 03 80 */ match_byte_assert(3); match_byte_assert(0x80); + match_byte_assert(0); + if (match_byte(0)) + { + match_zeros_assert(3); + if (!match_byte(0x10)) + match_byte_assert(0); + match_zeros_assert(4); + } +} + +static void +parse_weirdness(void) +{ + match_byte_assert(1); + get_u32(); + match_zeros_assert(12); + match_byte_assert(0x90); + match_byte_assert(1); match_zeros_assert(5); - if (!match_byte(0x10)) - match_byte_assert(0); - match_zeros_assert(4); + pos++; + match_zeros_assert(3); + puts(get_padded_string(32)); } static void @@ -545,21 +570,63 @@ match_NavTreeViewItem(void) match_byte_assert(7); match_byte_assert(0x80); match_zeros_assert(1); - if (!match_byte(0) && !match_byte(7)) + if (!match_byte(0) && !match_byte(7) && !match_byte(2)) match_byte_assert(8); match_zeros_assert(3); pos++; match_byte_assert(0); match_byte_assert(1); - match_zeros_assert(3); - if (!match_byte(0)) - match_byte_assert(1); - match_zeros_assert(5); - match_byte_assert(1); - match_zeros_assert(5); - - put_safe(get_string1()); - putc('\n', stdout); + match_byte_assert(0); + if (match_byte(0)) + { + match_zeros_assert(7); + if (!match_byte(0)) + match_byte_assert(1); + match_zeros_assert(5); + get_string1(); + if (match_byte(1)) + { + parse_weirdness(); + match_byte_assert(0); + pos++; + match_zeros_assert(11); + match_byte_assert(1); + match_zeros_assert(3); + get_string4(); + match_byte_assert(0); + if (match_byte(0)) + { + match_zeros_assert(2); + if (match_u32(8500)) + match_u32_assert(11000); + else + { + match_u32_assert(11000); + match_u32_assert(8500); + } + pos += 32; + get_string1(); + if (!match_byte(0)) + match_byte_assert(1); + pos++; + pos++; + pos++; + pos++; + get_string4(); /* page title */ + match_byte_assert(1); + match_byte_assert(1); + match_zeros_assert(3); + get_string4(); /* page number */ + match_byte_assert(0); + pos += 2; + match_u16_assert(2); + } + parse_flexible(); + } + else + match_zeros_assert(3); + } + //fprintf(stderr, "%#x ", pos - 16); } static void @@ -582,8 +649,6 @@ match_DspNumber(void) parse_DspNumber(); } -static void parse_flexible(void); - static void parse_DspCell(void) { @@ -600,6 +665,21 @@ match_DspCell(void) parse_DspCell(); } +static void +parse_NavLog(void) +{ + match_byte_assert(2); + pos += 32; +} + +static void +match_NavLog(void) +{ /* 09 80 */ + match_byte_assert(9); + match_byte_assert(0x80); + parse_NavLog(); +} + static void parse_PMModelItemInfo(void) { /* 54 80 */ @@ -631,9 +711,44 @@ match_PMPivotItemTree(void) match_PMModelItemInfo(); } +static void +parse_NavHead(void) +{ + match_byte_assert(2); + match_zeros_assert(24); + match_byte_assert(1); + match_zeros_assert(7); + match_DspSimpleText(); + parse_flexible(); +} + +static void +parse_NavOleItem(void) +{ + match_byte_assert(0); + match_byte_assert(1); + match_zeros_assert(2); + pos++; + match_zeros_assert(9); + match_byte_assert(1); + match_zeros_assert(10); + match_byte_assert(1); + match_zeros_assert(6); + match_byte_assert(1); + parse_weirdness(); + match_byte_assert(0); + pos++; + match_zeros_assert(11); + match_byte_assert(1); + match_zeros_assert(3); + get_string4(); + match_byte_assert(0); +} + static void parse_flexible(void) { + int start = pos; if (data[pos] == 0xff && data[pos + 1] == 0xff) { match_u16_assert(0xffff); @@ -645,43 +760,78 @@ parse_flexible(void) parse_DspNumber(); else if (!strcmp(heading, "DspString")) parse_DspString(); + else if (!strcmp(heading, "NavHead")) + parse_NavHead(); + else if (!strcmp(heading, "IndexedCollection")) + match_zeros_assert(14); + else if (!strcmp(heading, "NavOleItem")) + parse_NavOleItem(); else - assert(0); - } - else if (data[pos] == 0x2a && data[pos + 1] == 0x80) - match_DspNumber(); - else if (data[pos] == 0x27 && data[pos + 1] == 0x80) - match_DspCell(); - else if (data[pos] == 0x5 && data[pos + 1] == 0x80) - match_DspString(); - else if ((data[pos] == 0x3c || data[pos] == 0x39) - && data[pos + 1] == 0x80) - { - /* 3c 80 */ - /* 39 80 */ - pos += 2; - parse_format(); + { + fprintf(stderr, "don't know %s at offset 0x%x: ", heading, start); + hex_dump(stderr, pos, 64); + assert(0); + } + } + else if (data[pos + 1] == 0x80) + { + if (data[pos] == 0x2a && data[pos + 1] == 0x80) + match_DspNumber(); + else if (data[pos] == 0x27 && data[pos + 1] == 0x80) + match_DspCell(); + else if (data[pos] == 0x5 && data[pos + 1] == 0x80) + match_DspString(); + else if (data[pos] == 0x7 && data[pos + 1] == 0x80) + match_NavTreeViewItem(); + else if (data[pos] == 0x3 && data[pos + 1] == 0x80) + match_DspSimpleText(); + else if ((data[pos] == 0x3c || data[pos] == 0x39) + && data[pos + 1] == 0x80) + { + /* 3c 80 */ + /* 39 80 */ + pos += 2; + parse_format(); /* match_byte_assert(0x01); - match_byte_assert(0x02); - match_byte_assert(0x0d); */ + match_byte_assert(0x02); + match_byte_assert(0x0d); */ + } + else if (data[pos] == 0x15 && data[pos + 1] == 0x80) + { + /* 15 80 */ + data += 2; + match_byte_assert(2); + printf ("15 80(%f", get_double()); + printf (" %s)\n", get_string1()); + } + else if (data[pos] == 0x9 && data[pos + 1] == 0x80) + { + match_NavLog(); + } + else + { + fprintf (stderr, "bad record 0x%02x at offset %x\n", + data[pos], pos); + hex_dump (stderr, pos, 64); + assert(0); + } } - else if (data[pos] == 0x15 && data[pos + 1] == 0x80) + else if (match_byte(0xa)) { - /* 15 80 */ - data += 2; - match_byte_assert(2); - printf ("15 80(%f", get_double()); - printf (" %s)\n", get_string1()); + match_zeros_assert(5); + assert(pos == n); + exit (0); } else { - fprintf (stderr, "bad data cell 0x%02x at offset %x\n", - data[pos], pos); + fprintf (stderr, "bad record start at offset %x: ", pos); hex_dump (stderr, pos, 64); assert(0); } } + + int main(int argc, char *argv[]) { @@ -723,7 +873,7 @@ main(int argc, char *argv[]) exit(1); } n = s.st_size; - data = malloc(n); + data = malloc(n + 256); if (!data) { perror("malloc"); @@ -734,6 +884,8 @@ main(int argc, char *argv[]) perror("read"); exit(1); } + for (int i = 0; i < 256; i++) + data[n + i] = i % 2 ? 0xaa : 0x55; close(fd); setvbuf (stdout, NULL, _IOLBF, 0); @@ -756,39 +908,63 @@ main(int argc, char *argv[]) parse_heading("NavTreeViewItem"); match_byte_assert(0); - match_u32_assert(0); + if (!match_u32(1)) + match_u32_assert(0); match_byte_assert(2); match_byte_assert(0); match_byte_assert(1); match_zeros_assert(9); match_u32_assert(1); - assert (pos == 0xb0); - pos += 0x28; - match_zeros_assert(5); - if (match_u32(8500)) - match_u32_assert(11000); - else + match_u32_assert(0); + match_u32_assert(0x18); + if (!match_u32(0)) + match_u32_assert(0xffffffd8); + match_u32_assert(0xffffffde); + match_u32_assert(0x18); + if (!match_u32(0)) + match_u32_assert(0xffffffd8); + match_u32_assert(0x28); + match_u32_assert(0x28); + pos += 8; + if (data[pos] == 0) { - match_u32_assert(11000); - match_u32_assert(8500); + match_zeros_assert(5); + + if (match_u32(8500)) + match_u32_assert(11000); + else + { + match_u32_assert(11000); + match_u32_assert(8500); + } + pos += 32; + get_string1(); + if (!match_byte(0)) + match_byte_assert(1); + pos++; + pos++; + pos++; + pos++; + get_string4(); /* page title */ + match_byte_assert(1); + match_byte_assert(1); + match_zeros_assert(3); + get_string4(); /* page number */ + match_byte_assert(0); + pos += 2; + match_u16_assert(2); } - pos = 0x105; - match_string1_assert("(Continued)"); - match_byte_assert(1); - match_byte_assert(1); - match_zeros_assert(3); - get_string4(); /* page title */ - match_byte_assert(1); - match_byte_assert(1); - match_zeros_assert(3); - get_string4(); /* page number */ - match_byte_assert(0); - pos += 2; - match_u16_assert(2); + if (data[pos + 9] != 'L') + exit(0); parse_heading("NavLog"); - pos = 0x36b; + parse_NavLog(); + parse_flexible(); + parse_flexible(); + parse_flexible(); + parse_flexible(); + exit(0); puts(get_padded_string(32)); if (!match_u32(80)) match_u32_assert(132); @@ -799,12 +975,7 @@ main(int argc, char *argv[]) match_byte_assert(0); parse_heading("NavHead"); - match_byte_assert(2); - match_zeros_assert(24); - match_u32_assert(1); - match_u32_assert(0); - match_DspSimpleText(); - match_DspString(); + parse_NavHead(); match_NavTreeViewItem(); match_zeros_assert(3); @@ -868,6 +1039,7 @@ main(int argc, char *argv[]) match_zeros_assert(3); match_byte_assert(1); match_byte_assert(0); + match_zeros_assert(7); while (data[pos] != 1) { diff --git a/spo-notes b/spo-notes index b70a71d4b3..95b212e052 100644 --- a/spo-notes +++ b/spo-notes @@ -726,7 +726,8 @@ When the top-level "Output" node is selected for save: (This is a valid spot for the file to contain 00000000 then eof) -02ee ffff 0000 "NavLog" 02 i0*2 i24 +02ee ffff 0000 "NavLog" +02fa 02 i0*2 i24 0307 (i0 | i-40) (i691 | i987) (2-3 digit negative int) i1 0317 i0 0318 03 80 00*10 -- 2.30.2