aboutsummaryrefslogtreecommitdiffstats
path: root/src/header.c
blob: e92fd5d094750f86160079fcdbaec80cab1dee46 (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
#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);
	}
  }

}