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 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
|
#include "delo.h"
#define _SECTOR_SIZE 512
#define MSDOS_LABEL_MAGIC 0xAA55
#define DOS_EXTENDED_PARTITION 5
#define LINUX_EXTENDED_PARTITION 0x85
#define WIN98_EXTENDED_PARTITION 0x0f
#define LINUX_NATIVE 0x83
extern void *malloc(int);
struct partition {
unsigned char boot_ind; /* 0x80 - active */
unsigned char head; /* starting head */
unsigned char sector; /* starting sector */
unsigned char cyl; /* starting cylinder */
unsigned char sys_ind; /* What partition type */
unsigned char end_head; /* end head */
unsigned char end_sector; /* end sector */
unsigned char end_cyl; /* end cylinder */
unsigned int start_sect; /* starting sector counting from 0 */
unsigned int nr_sects; /* nr of sectors in partition */
};
unsigned int getpartoffset(char *partition) {
int fd, i, k,
pno=0,
j,estart,pstart,retval;
unsigned char *fb=malloc(512) + 8; /* Unaligned */
struct partition *p=0,
*ep=0;
/* Convert partition number (ascii) to int
* This might be empty - pno will be 0 and we
* will take the first ext2/linux partition */
for(i=0;partition[i]!=0x0;i++)
pno=pno*10 + partition[i] - '0';
#ifdef DEBUG
printf("Partition '%s' %d\n",partition, pno);
#endif
/* Read first sector */
retval=bootread(0,fb,1 * _SECTOR_SIZE);
/* Copy 2 bytes to back - Unaligned stuff :( */
for(k=_SECTOR_SIZE;k>=0;--k)
fb[k+2]=fb[k];
#ifdef DEBUG
printf("bootread returned %d\n",retval);
#endif
if (*(unsigned short *) (fb + 0x1fe + 2) != MSDOS_LABEL_MAGIC) {
puts("No DOS disklabel found");
return 0;
}
#ifdef DEBUG
puts("DOS disklabel found");
#endif
p = (struct partition *) ( fb + 0x1be + 2 );
for(i=1;i<=4;i++) {
#ifdef DEBUG
printf("%2d %2x %2x %8d %8d\n", i, p->boot_ind, p->sys_ind,
p->start_sect, p->nr_sects);
#endif
/* Ignore empty partitions */
if (!p->nr_sects)
continue;
/* Ignore extended now */
if (p->sys_ind == DOS_EXTENDED_PARTITION ||
p->sys_ind == LINUX_EXTENDED_PARTITION ||
p->sys_ind == WIN98_EXTENDED_PARTITION) {
/* Store extended partition pointer for later */
ep=p;
estart=pstart=p->start_sect;
continue;
}
/* If we found the partition pno or we
* want the first native partition */
if (i == pno || p->sys_ind == LINUX_NATIVE && pno == 0)
return(p->start_sect);
p++;
}
while(ep != 0) {
/* Read extended partition start */
bootread(pstart, fb, 1 * _SECTOR_SIZE);
/* Copy 2 bytes to back - Unaligned stuff :( */
for(k=_SECTOR_SIZE;k>=0;--k)
fb[k+2]=fb[k];
/* If this doesnt contain a LABEL_MAGIC we havent got
* any further partition tables */
if (*(unsigned short *) (fb + 0x1fe + 2) != MSDOS_LABEL_MAGIC) {
printf("Magic failed\n");
break;
}
ep=0;
p=(struct partition *) ( fb + 0x1be + 2 );
for(j=1;j<=4;j++,p++) {
if (!p->nr_sects)
continue;
if (p->sys_ind == DOS_EXTENDED_PARTITION ||
p->sys_ind == LINUX_EXTENDED_PARTITION ||
p->sys_ind == WIN98_EXTENDED_PARTITION) {
pstart=estart + p->start_sect;
ep=p;
continue;
}
#ifdef DEBUG
printf("%2d %2x %2x %8d %8d\n", i, p->boot_ind,
p->sys_ind,
p->start_sect, p->nr_sects);
#endif
/* if we got pno or we want the first linux native */
if (pno == i || p->sys_ind == LINUX_NATIVE && pno == 0)
return(estart + p->start_sect);
i++;
}
}
return(0);
}
|