aboutsummaryrefslogtreecommitdiffstats
path: root/src/header.c
blob: 4e689342095cd1bca94ab39fa280ed40b3705b42 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#include "project.h"


#define TABLE_SIZE (((sizeof(GPT_entry)*GPT_PARITION_ENTRIES)/SECTOR_SIZE)+2)

void
header_calc_crc (GPT_header * h)
{

  h->header_crc = 0;
  h->header_crc = crc32 (0, h, sizeof (GPT_header));

}

GPT_header
header_new (GUID disk_guid, int lbas, int alt)
{
  GPT_header ret = { 0 };

  memcpy (ret.signature, GPT_HEADER_SIGNATURE, sizeof (ret.signature));
  ret.revision = GPT_HEADER_REVISION_EFI10;
  ret.header_size = sizeof (GPT_header);

  ret.first_usable_lba = TABLE_SIZE;
  ret.last_usable_lba = lbas - TABLE_SIZE;

  ret.n_partition_entries = GPT_PARITION_ENTRIES;
  ret.partition_entry_size = sizeof (GPT_entry);

  ret.disk_guid = disk_guid;

  if (!alt)
    {
      ret.my_lba = 1;
      ret.alternate_lba = lbas - 1;
      ret.partition_entry_lba = 2;
    }
  else
    {
      ret.my_lba = lbas - 1;
      ret.alternate_lba = 1;
      ret.partition_entry_lba = lbas - TABLE_SIZE;
    }

  header_calc_crc (&ret);

  return ret;
}



uint32_t
header_calc_ent_crc (DISK * d, GPT_header * h)
{
  int i;
  GPT_entry e;
  uint32_t crc = 0;


  for (i = 0; i < h->n_partition_entries; ++i)
    {
      e = entry_read (d, h, i);
      crc = crc32 (crc, &e, h->partition_entry_size);
    }

  return crc;
}


void
header_show (DISK * d, GPT_header * h)
{
  GPT_header c = *h;
  uint32_t crc;
  int i;

  if (h->my_lba < h->alternate_lba)
    {
      printf ("  GPT:\n");
    }
  else
    {
      printf ("  ALTERNATE GPT:\n");
    }

  c.header_crc = 0;
  crc = crc32 (0, &c, sizeof (c));

  printf ("    Signature %s, CRC %s\n",
          (memcmp (h->signature, GPT_HEADER_SIGNATURE, sizeof (h->signature)))
          ? "INVALID" : "valid",
          (crc == h->header_crc) ? "matches" : "DOES NOT MATCH");

  printf ("    rev=0x%08x lba=%lld alternate=%lld\n",
          h->revision, (long long) h->my_lba, (long long) h->alternate_lba);
  printf ("    usable lbas %lld-%lld\n",
          (long long) h->first_usable_lba, (long long) h->last_usable_lba);

  printf ("    DISK GUID: %s\n", guid_to_a (h->disk_guid));


  crc = header_calc_ent_crc (d, h);

  printf ("    patitions (at lba %lld) CRC %s:\n",
          (long long) h->partition_entry_lba,
          (crc == h->partition_entry_crc) ? "matches" : "DOES NOT MATCH");

  for (i = 0; i < h->n_partition_entries; ++i)
    {
      GPT_entry e = entry_read (d, h, i);
      if (!entry_empty (&e))
        {
          printf ("      %d:\n", i);
          entry_show (&e);
        }
    }

}