// File: tsfn[P]doc2txt/src/doc_property.cpp
// Function: parse_summary_information(Storage const&)
bool parse_summary_information(const Storage &st) {
  // 取得\005SummaryInformation Stream
  char sis_name[64];
  sis_name[0] = 5, sis_name[1] = 0;
  sprintf(sis_name + 2, "SummaryInformation");
  const uchar *sis;
  uint sis_size;
  if (!st.stream(sis_name, &sis, &sis_size)) {
    return false;
  }


  // 读取\005SummaryInformation Stream
  /*
  for (int i = 0; i < 324; ++i) {
    printf("[%04X] = %02X\n", i, sis[i]);
  }
  */

  /* \005SummaryInformation Stream是一个PropertySetStream
   * PropertySetStream {
   *   ByteOrder: (2 bytes);
   *   Version: (2 bytes);
   *   SystemIdentifier: (4 bytes);
   *   CLSID: (16 bytes);
   *   NumPropertySets: (4 bytes);
   *   FMTIDO: (16 bytes);
   *   Offset0: (4 bytes);
   *   FMTID1: (0 bytes);
   *   Offset1: (0 bytes);
   *   PropertySet0: PropertySet (variable);
   *   PropertySet1: PropertySet (variable);
   *   Padding (variable);
   * }
   * PropertySet {
   *   Size: (4 bytes); // 这个结构的中大小
   *   NumProperties: (4 bytes); // 这个结构有多少个Property
   *   PropertyIdentifierAndOffset[] {
   *     PropertyIdentifier: (4 bytes); // Property编号
   *     Offset: (4 bytes); // 从PropertySet的起始位置开始的偏移量
   *   }
   *   Property[] {
   *     TypedPropertyValue {
   *       Type: PropertyType (2 bytes);
   *       Padding: (2 bytes);
   *       Value: (variable) {
   *         Type=0x0008: CodePageString;
   *         Type=0x0040: FILETIME (Packet Version);
   *       }
   *     }
   *   }
   * }
   */

  FILE *out_file = fopen("./property.txt", "wb");

  const uchar *ps = sis + 48;
  uint pre_size = 0;
  uint num_property_set = *(uint *)(sis + 24);
  for (uint set_id = 0; set_id < num_property_set; ++set_id) {
    ps += pre_size;
    pre_size = *(uint *)(ps);
    uint num_properties = *(uint *)(ps + 4);
    printf("num_properties = %u\n", num_properties);
    for (uint i = 0; i < num_properties; ++i) {
      uint pid = *(uint *)(ps + 8 + 8 * i);
      uint offset = *(uint *)(ps + 8 + 8 * i + 4);
      ushort type = *(ushort *)(ps + offset);
      ushort padding = *(ushort *)(ps + offset + 2);
      printf("pid = %u, offset = %u, type = 0x%04X, padding = %d\n",
          pid, offset, type, padding);
      const uchar *value = ps + offset + 4;
      if (type == 0x001E) {
        uint size = *(uint *)(value);
        // printf("size = %u\n", size);
        printf("-> %s\n", (char *)(value + 4));
        for (uint i = 0; i < size; ++i) {
          // fputc(value[4 + i], out_file);
          // printf("value[0x%02X] = 0x%02X\n", 4 + i, value[4 + i]);
          // fputc(value[4 + i], file);
        }
      }
    }
  }
  fclose(out_file);
  return true;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xa0, %rsp
movq %rdi, -0x10(%rbp)
movb $0x5, -0x50(%rbp)
movb $0x0, -0x4f(%rbp)
leaq -0x50(%rbp), %rdi
addq $0x2, %rdi
leaq 0x3ea(%rip), %rsi       # 0x6100
movb $0x0, %al
callq 0x1060
movq -0x10(%rbp), %rdi
leaq -0x50(%rbp), %rsi
leaq -0x58(%rbp), %rdx
leaq -0x5c(%rbp), %rcx
callq 0x1e80
testb $0x1, %al
jne 0x5d3f
movb $0x0, -0x1(%rbp)
jmp 0x5f05
leaq 0x3cd(%rip), %rdi       # 0x6113
leaq 0x2f5(%rip), %rsi       # 0x6042
callq 0x1150
movq %rax, -0x68(%rbp)
movq -0x58(%rbp), %rax
addq $0x30, %rax
movq %rax, -0x70(%rbp)
movl $0x0, -0x74(%rbp)
movq -0x58(%rbp), %rax
movl 0x18(%rax), %eax
movl %eax, -0x78(%rbp)
movl $0x0, -0x7c(%rbp)
movl -0x7c(%rbp), %eax
cmpl -0x78(%rbp), %eax
jae 0x5ef8
movl -0x74(%rbp), %ecx
movq -0x70(%rbp), %rax
movl %ecx, %ecx
addq %rcx, %rax
movq %rax, -0x70(%rbp)
movq -0x70(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x74(%rbp)
movq -0x70(%rbp), %rax
movl 0x4(%rax), %eax
movl %eax, -0x80(%rbp)
movl -0x80(%rbp), %esi
leaq 0x36f(%rip), %rdi       # 0x6122
movb $0x0, %al
callq 0x1040
movl $0x0, -0x84(%rbp)
movl -0x84(%rbp), %eax
cmpl -0x80(%rbp), %eax
jae 0x5ee8
movq -0x70(%rbp), %rax
movl -0x84(%rbp), %ecx
shll $0x3, %ecx
movl %ecx, %ecx
movl 0x8(%rax,%rcx), %eax
movl %eax, -0x88(%rbp)
movq -0x70(%rbp), %rax
movl -0x84(%rbp), %ecx
shll $0x3, %ecx
movl %ecx, %ecx
movl 0xc(%rax,%rcx), %eax
movl %eax, -0x8c(%rbp)
movq -0x70(%rbp), %rax
movl -0x8c(%rbp), %ecx
movw (%rax,%rcx), %ax
movw %ax, -0x8e(%rbp)
movq -0x70(%rbp), %rax
movl -0x8c(%rbp), %ecx
movw 0x2(%rax,%rcx), %ax
movw %ax, -0x90(%rbp)
movl -0x88(%rbp), %esi
movl -0x8c(%rbp), %edx
movzwl -0x8e(%rbp), %ecx
movzwl -0x90(%rbp), %r8d
leaq 0x2e5(%rip), %rdi       # 0x6137
movb $0x0, %al
callq 0x1040
movq -0x70(%rbp), %rax
movl -0x8c(%rbp), %ecx
addq %rcx, %rax
addq $0x4, %rax
movq %rax, -0x98(%rbp)
movzwl -0x8e(%rbp), %eax
cmpl $0x1e, %eax
jne 0x5ed2
movq -0x98(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x9c(%rbp)
movq -0x98(%rbp), %rsi
addq $0x4, %rsi
leaq 0x2cd(%rip), %rdi       # 0x616b
movb $0x0, %al
callq 0x1040
movl $0x0, -0xa0(%rbp)
movl -0xa0(%rbp), %eax
cmpl -0x9c(%rbp), %eax
jae 0x5ed0
jmp 0x5ebf
movl -0xa0(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xa0(%rbp)
jmp 0x5eaf
jmp 0x5ed2
jmp 0x5ed4
movl -0x84(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x84(%rbp)
jmp 0x5dc4
jmp 0x5eea
movl -0x7c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x7c(%rbp)
jmp 0x5d7a
movq -0x68(%rbp), %rdi
callq 0x10f0
movb $0x1, -0x1(%rbp)
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0xa0, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)