File: msdos.c

package info (click to toggle)
delo 0.7-8
  • links: PTS
  • area: main
  • in suites: woody
  • size: 444 kB
  • ctags: 148
  • sloc: ansic: 931; perl: 235; makefile: 145; sh: 132; asm: 15
file content (141 lines) | stat: -rw-r--r-- 3,347 bytes parent folder | download
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);	
}