2
* GRUB Utilities -- Utilities for GRUB Legacy, GRUB2 and GRUB for DOS
3
* Copyright (C) 2007 Bean (bean123@126.com)
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 2 of the License, or
8
* (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22
#define _FILE_OFFSET_BITS 64 // This is required to enable 64-bit off_t
32
static unsigned char ebuf[512];
36
#ifdef __GNUC__ // Mingw or Cygwin
38
#define u_off_t off64_t
39
#define u_lseek lseek64
43
#define u_off_t __int64
44
#define u_lseek _lseeki64
50
#define u_off_t off_t // In FreeBSD, off_t is 64-bit !
55
int go_sect(int hd,unsigned long sec)
57
// Test if 64-bit seek is supported
58
if (sizeof(u_off_t)>=8)
64
rs=u_lseek(hd,bs,SEEK_SET);
75
return (lseek(hd,bs[0],SEEK_SET)!=bs[0]);
79
// Partition enumerator
80
// xe->cur is the current partition number, before the first call to xd_enum,
81
// it should be set to 0xFF
82
// xe->nxt is the target partition number, if it equals 0xFF, it means enumerate
83
// all partitions, otherwise, it means jump to the specific partition.
84
int xd_enum(int hd,xde_t* xe)
92
unsigned long pt[4][2];
97
if (read(hd,ebuf,nn)!=nn)
99
if (valueat(ebuf,0x1FE,unsigned short)!=0xAA55)
102
for (i=0x1BE;i<0x1FE;i+=16)
105
if ((pt[np][1]=valueat(ebuf,i+12,unsigned long))==0)
107
pt[np++][0]=valueat(ebuf,i+8,unsigned long);
111
// Sort partition table base on start address
116
if (pt[k][0]>pt[j][0]) k=j;
129
// Should have space for MBR
132
// Check for partition overlap
134
if (pt[i][0]+pt[i][1]>pt[i+1][0])
140
if ((unsigned char)cc>xe->nxt)
147
if (! ebuf[xe->nxt*16+4+0x1BE])
150
xe->dfs=ebuf[xe->nxt*16+4+0x1BE];
151
xe->bse=valueat(ebuf,xe->nxt*16+8+0x1BE,unsigned long);
152
xe->len=valueat(ebuf,xe->nxt*16+12+0x1BE,unsigned long);
155
else if (xe->nxt!=0xFF)
159
if (ebuf[cc*16+4+0x1BE])
162
xe->dfs=ebuf[cc*16+4+0x1BE];
163
xe->bse=valueat(ebuf,cc*16+8+0x1BE,unsigned long);
164
xe->len=valueat(ebuf,cc*16+12+0x1BE,unsigned long);
174
// Scan for extended partition
176
if ((ebuf[i*16+4+0x1BE]==5) || (ebuf[i*16+4+0x1BE]==0xF)) break;
179
xe->ebs=xe->bse=valueat(ebuf,i*16+8+0x1BE,unsigned long);
183
// Is end of extended partition chain ?
184
if ((ebuf[4+0x1CE]!=0x5) && (ebuf[4+0x1CE]!=0xF) ||
185
(valueat(ebuf,8+0x1CE,unsigned long)==0))
187
xe->bse=xe->ebs+valueat(ebuf,8+0x1CE,unsigned long);
194
if (go_sect(hd,xe->bse))
197
if (read(hd,ebuf,nn)!=nn)
200
if (valueat(ebuf,0x1FE,unsigned short)!=0xAA55)
203
if ((ebuf[4+0x1BE]==5) || (ebuf[4+0x1BE]==0xF))
204
if (valueat(ebuf,8+0x1BE,unsigned long)==0)
208
xe->bse=xe->ebs+valueat(ebuf,8+0x1BE,unsigned long);
213
kk=(ebuf[4+0x1BE]!=0);
214
if ((kk) && ((xe->nxt==0xFF) || (cc==xe->nxt)))
217
xe->dfs=ebuf[4+0x1BE];
218
xe->bse+=valueat(ebuf,8+0x1BE,unsigned long);
219
xe->len=valueat(ebuf,12+0x1BE,unsigned long);
226
#define EXT2_SUPER_MAGIC 0xEF53
228
int mbr_nhd, mbr_spt;
230
void split_chs(unsigned char* chs,unsigned long* c,unsigned long* h,unsigned long* s)
233
*s=(chs[1] & 0x3F)-1;
234
*c=((unsigned long)(chs[1]>>6))*256+chs[2];
237
int chk_chs(unsigned long nhd,unsigned long spt,unsigned long lba,unsigned char* chs)
241
split_chs(chs,&c,&h,&s);
243
return ((nhd==h+1) && (spt==s+1));
245
return (c*nhd*spt+h*spt+s==lba);
248
int chk_mbr(unsigned char* buf)
250
unsigned long nhd,spt,a1,a2,c2,h2,s2;
254
while ((i<0x1FE) && (buf[i+4]==0))
258
a1=valueat(buf[i],8,unsigned long);
259
a2=a1+valueat(buf[i],12,unsigned long)-1;
262
split_chs(buf+i+5,&c2,&h2,&s2);
267
if (! chk_chs(nhd,spt,a1,buf+i+1))
272
unsigned long c1,h1,s1;
275
split_chs(buf+i+1,&c1,&h1,&s1);
276
if ((c1==0x3FF) || (c1>c2))
278
n1=(long)(c1*a2)-(long)(c2*a1)-(long)(c1*s2)+(long)(c2*s1);
279
n2=(long)(c1*h2)-(long)(c2*h1);
285
if ((n2==0) || (n1<=0) || (n1 % n2))
287
spt=(unsigned long)(n1/n2);
290
n1=(long)a2-(long)s2-(long)(h2*spt);
292
if ((n2==0) || (n1<=0) || (n1 % n2))
294
nhd=(unsigned long)(n1/n2);
299
if ((nhd==0) || (nhd>255) || (spt==0) || (spt>63))
306
if ((! chk_chs(nhd,spt,valueat(buf[i],8,unsigned long),buf+i+1)) ||
307
(! chk_chs(nhd,spt,valueat(buf[i],8,unsigned long)+valueat(buf[i],12,unsigned long)-1,buf+i+5)))
317
int get_fstype(unsigned char* buf)
322
// The first sector of EXT2 might not contain the 0xAA55 signature
323
if (valueat(buf[1024],56,unsigned short)==EXT2_SUPER_MAGIC)
325
if (valueat(buf[0],0x1FE,unsigned short)!=0xAA55)
327
if (! strncmp(&buf[0x36],"FAT",3))
328
return ((buf[0x26]==0x28) || (buf[0x26]==0x29))?FST_FAT16:FST_OTHER;
329
if (! strncmp(&buf[0x52],"FAT32",5))
330
return ((buf[0x42]==0x28) || (buf[0x42]==0x29))?FST_FAT32:FST_OTHER;
331
if (! strncmp(&buf[0x3],"NTFS",4))
332
return ((buf[0]==0xEB) && (buf[1]==0x52))?FST_NTFS:FST_OTHER;
336
char* fst2str(int fs)
344
return "FAT12/FAT16";
361
static fstab_t fstab[]= {
383
char* dfs2str(int fs)
387
for (i=0;fstab[i].id;i++)
2
* GRUB Utilities -- Utilities for GRUB Legacy, GRUB2 and GRUB for DOS
3
* Copyright (C) 2007 Bean (bean123@126.com)
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 2 of the License, or
8
* (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22
#define _FILE_OFFSET_BITS 64 // This is required to enable 64-bit off_t
32
static unsigned char ebuf[512];
36
#ifdef __GNUC__ // Mingw or Cygwin
38
#define u_off_t off64_t
39
#define u_lseek lseek64
43
#define u_off_t __int64
44
#define u_lseek _lseeki64
50
#define u_off_t off_t // In FreeBSD, off_t is 64-bit !
55
int go_sect(int hd,unsigned long sec)
57
// Test if 64-bit seek is supported
58
if (sizeof(u_off_t)>=8)
64
rs=u_lseek(hd,bs,SEEK_SET);
75
return (lseek(hd,bs[0],SEEK_SET)!=bs[0]);
79
// Partition enumerator
80
// xe->cur is the current partition number, before the first call to xd_enum,
81
// it should be set to 0xFF
82
// xe->nxt is the target partition number, if it equals 0xFF, it means enumerate
83
// all partitions, otherwise, it means jump to the specific partition.
84
int xd_enum(int hd,xde_t* xe)
92
unsigned long pt[4][2];
97
if (read(hd,ebuf,nn)!=nn)
99
if (valueat(ebuf,0x1FE,unsigned short)!=0xAA55)
102
for (i=0x1BE;i<0x1FE;i+=16)
105
if ((pt[np][1]=valueat(ebuf,i+12,unsigned long))==0)
107
pt[np++][0]=valueat(ebuf,i+8,unsigned long);
111
// Sort partition table base on start address
116
if (pt[k][0]>pt[j][0]) k=j;
129
// Should have space for MBR
132
// Check for partition overlap
134
if (pt[i][0]+pt[i][1]>pt[i+1][0])
140
if ((unsigned char)cc>xe->nxt)
147
if (! ebuf[xe->nxt*16+4+0x1BE])
150
xe->dfs=ebuf[xe->nxt*16+4+0x1BE];
151
xe->bse=valueat(ebuf,xe->nxt*16+8+0x1BE,unsigned long);
152
xe->len=valueat(ebuf,xe->nxt*16+12+0x1BE,unsigned long);
155
else if (xe->nxt!=0xFF)
159
if (ebuf[cc*16+4+0x1BE])
162
xe->dfs=ebuf[cc*16+4+0x1BE];
163
xe->bse=valueat(ebuf,cc*16+8+0x1BE,unsigned long);
164
xe->len=valueat(ebuf,cc*16+12+0x1BE,unsigned long);
174
// Scan for extended partition
176
if ((ebuf[i*16+4+0x1BE]==5) || (ebuf[i*16+4+0x1BE]==0xF)) break;
179
xe->ebs=xe->bse=valueat(ebuf,i*16+8+0x1BE,unsigned long);
183
// Is end of extended partition chain ?
184
if ((ebuf[4+0x1CE]!=0x5) && (ebuf[4+0x1CE]!=0xF) ||
185
(valueat(ebuf,8+0x1CE,unsigned long)==0))
187
xe->bse=xe->ebs+valueat(ebuf,8+0x1CE,unsigned long);
194
if (go_sect(hd,xe->bse))
197
if (read(hd,ebuf,nn)!=nn)
200
if (valueat(ebuf,0x1FE,unsigned short)!=0xAA55)
203
if ((ebuf[4+0x1BE]==5) || (ebuf[4+0x1BE]==0xF))
204
if (valueat(ebuf,8+0x1BE,unsigned long)==0)
208
xe->bse=xe->ebs+valueat(ebuf,8+0x1BE,unsigned long);
213
kk=(ebuf[4+0x1BE]!=0);
214
if ((kk) && ((xe->nxt==0xFF) || (cc==xe->nxt)))
217
xe->dfs=ebuf[4+0x1BE];
218
xe->bse+=valueat(ebuf,8+0x1BE,unsigned long);
219
xe->len=valueat(ebuf,12+0x1BE,unsigned long);
226
#define EXT2_SUPER_MAGIC 0xEF53
228
int mbr_nhd, mbr_spt;
230
void split_chs(unsigned char* chs,unsigned long* c,unsigned long* h,unsigned long* s)
233
*s=(chs[1] & 0x3F)-1;
234
*c=((unsigned long)(chs[1]>>6))*256+chs[2];
237
int chk_chs(unsigned long nhd,unsigned long spt,unsigned long lba,unsigned char* chs)
241
split_chs(chs,&c,&h,&s);
243
return ((nhd==h+1) && (spt==s+1));
245
return (c*nhd*spt+h*spt+s==lba);
248
int chk_mbr(unsigned char* buf)
250
unsigned long nhd,spt,a1,a2,c2,h2,s2;
254
while ((i<0x1FE) && (buf[i+4]==0))
258
a1=valueat(buf[i],8,unsigned long);
259
a2=a1+valueat(buf[i],12,unsigned long)-1;
262
split_chs(buf+i+5,&c2,&h2,&s2);
267
if (! chk_chs(nhd,spt,a1,buf+i+1))
272
unsigned long c1,h1,s1;
275
split_chs(buf+i+1,&c1,&h1,&s1);
276
if ((c1==0x3FF) || (c1>c2))
278
n1=(long)(c1*a2)-(long)(c2*a1)-(long)(c1*s2)+(long)(c2*s1);
279
n2=(long)(c1*h2)-(long)(c2*h1);
285
if ((n2==0) || (n1<=0) || (n1 % n2))
287
spt=(unsigned long)(n1/n2);
290
n1=(long)a2-(long)s2-(long)(h2*spt);
292
if ((n2==0) || (n1<=0) || (n1 % n2))
294
nhd=(unsigned long)(n1/n2);
299
if ((nhd==0) || (nhd>255) || (spt==0) || (spt>63))
306
if ((! chk_chs(nhd,spt,valueat(buf[i],8,unsigned long),buf+i+1)) ||
307
(! chk_chs(nhd,spt,valueat(buf[i],8,unsigned long)+valueat(buf[i],12,unsigned long)-1,buf+i+5)))
317
int get_fstype(unsigned char* buf)
322
// The first sector of EXT2 might not contain the 0xAA55 signature
323
if (valueat(buf[1024],56,unsigned short)==EXT2_SUPER_MAGIC)
325
if (valueat(buf[0],0x1FE,unsigned short)!=0xAA55)
327
if (! strncmp(&buf[0x36],"FAT",3))
328
return ((buf[0x26]==0x28) || (buf[0x26]==0x29))?FST_FAT16:FST_OTHER;
329
if (! strncmp(&buf[0x52],"FAT32",5))
330
return ((buf[0x42]==0x28) || (buf[0x42]==0x29))?FST_FAT32:FST_OTHER;
331
if (! strncmp(&buf[0x3],"NTFS",4))
332
return ((buf[0]==0xEB) && (buf[1]==0x52))?FST_NTFS:FST_OTHER;
336
char* fst2str(int fs)
344
return "FAT12/FAT16";
361
static fstab_t fstab[]= {
383
char* dfs2str(int fs)
387
for (i=0;fstab[i].id;i++)