From a501062f338339d1dbafebc55841cbdc570a27b6 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 9 Sep 2007 22:29:50 +0000 Subject: *** empty log message *** --- src/add.c | 21 +++++++++ src/disk.c | 73 +++++++++++++++++++++++++++++ src/disk.h | 6 +++ src/entry.c | 40 ++++++++++++++++ src/gpt.c | 41 +++++++++-------- src/guid.c | 130 +++++++++++++++++++++++++++------------------------- src/header.c | 137 +++++++++++++++++++++++++++++++++++++++++++------------ src/new.c | 47 +++++++++++++++++++ src/pmbr.c | 58 +++++++++++++++++++++++ src/prototypes.h | 30 ++++++++++-- src/show.c | 31 +++++++++++++ src/util.c | 21 +++++++++ 12 files changed, 521 insertions(+), 114 deletions(-) create mode 100644 src/add.c create mode 100644 src/disk.c create mode 100644 src/disk.h create mode 100644 src/entry.c create mode 100644 src/new.c create mode 100644 src/pmbr.c create mode 100644 src/show.c diff --git a/src/add.c b/src/add.c new file mode 100644 index 0000000..fb6bf25 --- /dev/null +++ b/src/add.c @@ -0,0 +1,21 @@ +#include "project.h" + + + +void add(DISK *d,int n,char *guid,int start,int end) +{ +GPT_header *h; +GPT_entry *e; + +uint8_t buf[512]; + +disk_read(d,buf,1,1); +h=(GPT_header *)buf; + +} + + + + + + diff --git a/src/disk.c b/src/disk.c new file mode 100644 index 0000000..8ccaf8e --- /dev/null +++ b/src/disk.c @@ -0,0 +1,73 @@ + +#include "project.h" + + +DISK * +disk_open (char *fn) +{ + DISK *ret = calloc (1, sizeof (DISK)); + off_t o; + + ret->fd = open (fn, O_RDWR); + + if (ret->fd < 0) + { + free (ret); + return NULL; + } + + + ret->name = strdup (fn); + + ret->lbas = lseek (ret->fd, (off_t) 0, SEEK_END); + + + ret->lbas = ret->lbas / (uint64_t) SECTOR_SIZE; + + fprintf (stderr, "Opened %s with size of %d lbas\n", ret->name, + (int) ret->lbas); + + return ret; +} + +void +disk_read (DISK * d, void *buf, uint64_t lba, int lbas) +{ + lba *= SECTOR_SIZE; + + if (lseek (d->fd, lba, SEEK_SET) != lba) + { + perror ("lseek"); + abort (); + } + + lbas *= SECTOR_SIZE; + if (read (d->fd, buf, lbas) != lbas) + { + perror ("read"); + abort (); + } +} +void +disk_write (DISK * d, void *buf, uint64_t lba, int lbas) +{ + lba *= SECTOR_SIZE; + + if (lseek (d->fd, lba, SEEK_SET) != lba) + { + perror ("lseek"); + abort (); + } + + lbas *= SECTOR_SIZE; + if (write (d->fd, buf, lbas) != lbas) + { + perror ("write"); + abort (); + } +} + +uint64_t disk_lbas(DISK *d) +{ +return d->lbas; +} diff --git a/src/disk.h b/src/disk.h new file mode 100644 index 0000000..468813a --- /dev/null +++ b/src/disk.h @@ -0,0 +1,6 @@ + +typedef struct { + char *name; + int fd; + uint64_t lbas; +} DISK; diff --git a/src/entry.c b/src/entry.c new file mode 100644 index 0000000..2044813 --- /dev/null +++ b/src/entry.c @@ -0,0 +1,40 @@ +#include "project.h" + +void entry_write(DISK *d,GPT_header *h,int n,GPT_entry *e) +{ +uint8_t buf[SECTOR_SIZE]; +uint64_t lba=GPT_ENTRY_LBA (h, n); + +disk_read (d, buf, lba,1); +memcpy(&buf[GPT_ENTRY_OFFSET(h,n)],e,sizeof(*e)); +disk_write (d, buf, lba, 1); +} + +GPT_entry entry_read(DISK *d,GPT_header *h,int n) +{ +uint8_t buf[SECTOR_SIZE]; +GPT_entry e; + +disk_read (d, buf, GPT_ENTRY_LBA (h, n), 1); +memcpy(&e,&buf[GPT_ENTRY_OFFSET(h,n)],sizeof(e)); +return e; +} + + +int entry_empty(GPT_entry *e) { +GUID empty=GUID_TYPE_EMPTY; +return !guid_cmp(&e->type,&empty); +} + +void entry_show(GPT_entry *e) +{ +char name[sizeof(e->name)+1]; + +utf16_to_ascii(e->name,sizeof(e->name),name,sizeof(name)); + + +printf(" Name %s\n",name); +printf(" Flags %16x Label %s\n",(int) e->flags,guid_to_a(e->label)); +printf(" Start %10lld End %10lld Type %s\n",(long long) e->start,(long long) e->end,guid_to_a(e->type)); + +} diff --git a/src/gpt.c b/src/gpt.c index c0f4bf5..2084fca 100644 --- a/src/gpt.c +++ b/src/gpt.c @@ -6,10 +6,13 @@ * */ -static char rcsid[] = "$Id: gpt.c,v 1.2 2007/09/08 18:21:23 root Exp $"; +static char rcsid[] = "$Id: gpt.c,v 1.3 2007/09/09 22:29:50 root Exp $"; /* * $Log: gpt.c,v $ + * Revision 1.3 2007/09/09 22:29:50 root + * *** empty log message *** + * * Revision 1.2 2007/09/08 18:21:23 root * *** empty log message *** * @@ -26,34 +29,34 @@ static char rcsid[] = "$Id: gpt.c,v 1.2 2007/09/08 18:21:23 root Exp $"; int main (int argc, char *argv[]) { -int fd; -char buf[512]; -GPT_entry *e; -GPT_header *h; -int i,j; + DISK *d; -fd=open("/dev/sda",O_RDONLY); + d = disk_open ("/dev/sdb"); -read(fd,buf,512); -read(fd,buf,512); -h=(GPT_header *) buf; + //new(d); + add(d,1,"linux-ext3",10*1024*2,30*1024*2); + show(d); -header_print(h); +#if 0 + printf ("hecrc=%08x\n", header_calc_ent_crc (d, h)); + + + return 0; -for (i=0;i<2;++i) { -read(fd,buf,512); //hexdump(stderr,buf,0,512); -for (j=0;j<4;++j) { -e=(GPT_entry *) buf; -e+=j; -printf("%d,%d: %s\n",i,j,guid_to_a(e->type)); -} + for (j = 0; j < 4; ++j) + { + e = (GPT_entry *) buf; + e += j; + printf ("%d,%d: %s\n", i, j, guid_to_a (e->type)); + } } - return 0; +#endif +return 0; } diff --git a/src/guid.c b/src/guid.c index d9d5dcb..006c4e2 100644 --- a/src/guid.c +++ b/src/guid.c @@ -9,16 +9,18 @@ static struct known_struct { { GUID_TYPE_EMPTY, "empty"}, { GUID_TYPE_SYSTEM, "EFI SYSTEM"}, -{GUID_TYPE_LINUX_EXT3,"linux-ext3"}, -{GUID_TYPE_LINUX_SWAP,"linux-swap"}, -{GUID_TYPE_APPLE_HFS,"apple-hfs"}, - { {0}, NULL} + { GUID_TYPE_LINUX_EXT3, "linux-ext3"}, + { GUID_TYPE_LINUX_SWAP, "linux-swap"}, + { GUID_TYPE_APPLE_HFS, "apple-hfs"}, + { GUID_TYPE_APPLE_TV, "apple-tv"}, + { { 0}, NULL} }; -int guid_cmp(GUID *a,GUID *b) +int +guid_cmp (GUID * a, GUID * b) { -return memcmp(a,b,sizeof(GUID)); + return memcmp (a, b, sizeof (GUID)); } #define GUIDTOARETSIZE 80 @@ -49,74 +51,78 @@ guid_to_a (GUID g) } int -a_to_guid (char *a,GUID *g) +a_to_guid (char *a, GUID * g) { struct known_struct *ptr = known_guids; - int digit[32],ndigits=0,i; + int digit[32], ndigits = 0, i; while (ptr->name) { if (!strcmp (a, ptr->name)) - memcpy(g,&ptr->g,sizeof(GUID)); - return 0; + memcpy (g, &ptr->g, sizeof (GUID)); + return 0; } - while ((*a) && (ndigits!=32)) { - switch (*a) { - case ' ': - case '\t': - case '\n': - case '\r': - case '-': - break; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - digit[ndigits++]=(*a)-'0'; - break; - case 'A': - case 'B': - case 'C': - case 'D': - case 'E': - case 'F': - digit[ndigits++]=((*a)-'A')+0xA; - break; - - case 'a': - case 'b': - case 'c': - case 'd': - case 'e': - case 'f': - digit[ndigits++]=((*a)-'a')+0xa; - break; - defalt: - return -1; - } - } - -for (i=0;i<16;++i) { - g->d[i]=(digit[(i<<1)] << 4) | digit[(i<<1)+1]; -} + while ((*a) && (ndigits != 32)) + { + switch (*a) + { + case ' ': + case '\t': + case '\n': + case '\r': + case '-': + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + digit[ndigits++] = (*a) - '0'; + break; + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + digit[ndigits++] = ((*a) - 'A') + 0xA; + break; + + case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + digit[ndigits++] = ((*a) - 'a') + 0xa; + break; + defalt: + return -1; + } + } + + for (i = 0; i < 16; ++i) + { + g->d[i] = (digit[(i << 1)] << 4) | digit[(i << 1) + 1]; + } return 0; } - -GUID random_guid(void) + +GUID +guid_random (void) { -GUID ret; + GUID ret; -int fd=open("/dev/random",O_RDONLY); -read(fd,&ret,sizeof(ret)); -close(fd); -return ret; + int fd = open ("/dev/random", O_RDONLY); + read (fd, &ret, sizeof (ret)); + close (fd); + return ret; } diff --git a/src/header.c b/src/header.c index d577837..e92fd5d 100644 --- a/src/header.c +++ b/src/header.c @@ -1,36 +1,113 @@ #include "project.h" -void header_print(uint8_t *buf) + +#define TABLE_SIZE (((sizeof(GPT_entry)*GPT_PARITION_ENTRIES)/SECTOR_SIZE)+2) + +void +header_calc_crc (GPT_header * h) { -GPT_header *h=(GPT_header *) buf; - - -printf ("Signature %c%c%c%c%c%c%c%c\n", - h->signature[0], - h->signature[1], - h->signature[2], - h->signature[3], - h->signature[4], - h->signature[5], - h->signature[6], - h->signature[7]); - -printf("rev=0x%08x header_size=%d header_crc=0x%08x\n", - h->revision,h->header_size,h->header_crc); -printf("my_lba=%lld alternate_lba=%lld first_lba=%lld last_lba=%lld\n", - (long long) h->my_lba, (long long) h->alternate_lba, - (long long) h->first_usable_lba,(long long) h->last_usable_lba); - -printf("guid=%s\n",guid_to_a(h->disk_guid)); -printf("partition_entry_lba=%lld n_entries=%d ent_size=%d ents_crc=%08x\n", - (long long) h->partition_entry_lba, h->n_partition_entries, - h->partition_entry_size,h->partition_entry_crc); - -printf("%x\n",crc32(0,buf,92)); -h->header_crc=0; -printf("%x\n",crc32(0,buf,92)); -h->partition_entry_crc=0; -printf("%x\n",crc32(0,buf,92)); + + 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_lbaalternate_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;in_partition_entries;++i) { + GPT_entry e=entry_read(d,h,i); + if (!entry_empty(&e)) { + printf(" %d:\n",i); + entry_show(&e); + } + } + +} diff --git a/src/new.c b/src/new.c new file mode 100644 index 0000000..d8c177f --- /dev/null +++ b/src/new.c @@ -0,0 +1,47 @@ +#include "project.h" + + + + +void new(DISK *d) +{ +uint8_t buf[SECTOR_SIZE]; + +MBR m; +GPT_header h,alt_h; +GPT_entry e={0}; +GUID disk_guid; +uint64_t lbas; +int n; + +lbas=disk_lbas(d); + + +disk_guid=guid_random(); + +m=mbr_new(lbas); +memcpy(buf,&m,sizeof(m)); +disk_write(d,buf,0,1); + +h=header_new ( disk_guid, lbas,0); +alt_h=header_new(disk_guid,lbas,1); + +for (n=0;nbootable, + MBR_CYLINDER(e->chs_start.cs), + e->chs_start.head, + MBR_SECTOR(e->chs_start.cs), + e->start); + +printf(" system %02x end chs %5d/%3d/%2d end sector %10d\n", + e->system, + MBR_CYLINDER(e->chs_end.cs), + e->chs_end.head, + MBR_SECTOR(e->chs_end.cs), + e->size+e->start); +} +void mbr_show(MBR *m) +{ +int i; + +printf(" PMBR:\n"); + +for (i=0;i<4;++i) { +if (m->entry[i].system) { +printf(" Entry %d:\n",i); +mbr_entry_show(&m->entry[i]); +} +} +if (memcmp(m->signature,MBR_SIGNATURE,sizeof(m->signature))) { +printf(" Signature INVALID\n"); +} else { +printf(" Signature valid\n"); +} +} + +MBR mbr_new(uint64_t lbas) +{ +uint64_t cyls=lbas; +MBR ret={0}; + +cyls=cyls/(63*255); +if (cyls>1023) cyls=1023; + +ret.entry[0].bootable=0; +ret.entry[0].chs_start.cs=MBR_CS(0,1); +ret.entry[0].system=MBR_PARTITION_TYPE_EFI; +ret.entry[0].chs_end.head=254; +ret.entry[0].chs_end.cs=MBR_CS(cyls,63); +ret.entry[0].start=1; +ret.entry[0].size=lbas-1; + +memcpy(ret.signature,MBR_SIGNATURE,sizeof(ret.signature)); + +return ret; +} diff --git a/src/prototypes.h b/src/prototypes.h index a3f15d4..630e5c0 100644 --- a/src/prototypes.h +++ b/src/prototypes.h @@ -3,12 +3,36 @@ int main(int argc, char *argv[]); /* version.c */ /* util.c */ void hexdump(FILE *f, uint8_t *data, int s, int l); +void utf16_to_ascii(uint16_t *u16, int u16_len, uint8_t *u8, int u8_len); /* guid.c */ int guid_cmp(GUID *a, GUID *b); char *guid_to_a(GUID g); int a_to_guid(char *a, GUID *g); -GUID random_guid(void); +GUID guid_random(void); /* crc.c */ -uint32_t crc32(uint32_t crc, const uint8_t *buf, int len); +uint32_t crc32(uint32_t crc, const void *_buf, int len); /* header.c */ -void header_print(uint8_t *buf); +void header_calc_crc(GPT_header *h); +GPT_header header_new(GUID disk_guid, int lbas, int alt); +uint32_t header_calc_ent_crc(DISK *d, GPT_header *h); +void header_show(DISK *d, GPT_header *h); +/* disk.c */ +DISK *disk_open(char *fn); +void disk_read(DISK *d, void *buf, uint64_t lba, int lbas); +void disk_write(DISK *d, void *buf, uint64_t lba, int lbas); +uint64_t disk_lbas(DISK *d); +/* pmbr.c */ +void mbr_entry_show(MBR_entry *e); +void mbr_show(MBR *m); +MBR mbr_new(uint64_t lbas); +/* show.c */ +void show(DISK *d); +/* entry.c */ +void entry_write(DISK *d, GPT_header *h, int n, GPT_entry *e); +GPT_entry entry_read(DISK *d, GPT_header *h, int n); +int entry_empty(GPT_entry *e); +void entry_show(GPT_entry *e); +/* new.c */ +void new(DISK *d); +/* add.c */ +void add(DISK *d, int n, char *guid, int start, int end); diff --git a/src/show.c b/src/show.c new file mode 100644 index 0000000..6297c85 --- /dev/null +++ b/src/show.c @@ -0,0 +1,31 @@ +#include "project.h" + + + +void show(DISK *d) +{ +MBR *m; +GPT_header *h; +GPT_entry *e; + +uint8_t buf[512]; + +disk_read(d,buf,0,1); +m=(MBR *)buf; +mbr_show(m); + +disk_read(d,buf,1,1); +h=(GPT_header *)buf; +header_show(d,h); + +disk_read(d,buf,disk_lbas(d)-1,1); +h=(GPT_header *)buf; +header_show(d,h); + +} + + + + + + diff --git a/src/util.c b/src/util.c index 32071fd..6fddd57 100644 --- a/src/util.c +++ b/src/util.c @@ -52,4 +52,25 @@ hexdump (FILE * f, uint8_t * data, int s, int l) } +void utf16_to_ascii(uint16_t *u16,int u16_len,uint8_t *u8, int u8_len) +{ +u16_len >>=1; + +if (u8_len==1) { + *u8=0; + return; +} +while (*u16 && u16_len) { +*(u8++)=*(u16++); +u16_len--; +u8_len--; +if (u8_len==1) { + *u8=0; + return; +} +} + + *u8=0; + return; +} -- cgit v1.2.3