147
148
int afg,gfg,def_drive,def_part,time_out,hot_key,part_num;
148
149
int def_spt,def_hds,def_ssc,def_tsc;
149
char *save_fn,*restore_fn,*boot_file,boot_file_83[12],*key_name;
150
char *save_fn,*restore_fn,boot_file_83[12];
151
const char *key_name;
152
const char *boot_file;
150
153
unsigned short load_seg;
152
155
static char fn_buf[24];
154
char* get_disk_name(int n)
157
static char* get_disk_name(int n)
156
159
#if defined(WIN32)
157
160
sprintf(fn_buf,"\\\\.\\PhysicalDrive%d",n);
278
int chk_mbr(unsigned char* buf);
281
static void list(int hd)
284
285
xe.cur=xe.nxt=0xFF;
285
286
fprintf(stderr," # id base leng\n");
286
287
while (! xd_enum(hd,&xe))
287
fprintf(stderr,"%2d %02X %8X %8X\n",xe.cur,xe.dfs,xe.bse,xe.len);
288
fprintf(stderr,"%2d %02llX %8llX %8llX\n",xe.cur,
289
(unsigned long long) xe.dfs,
290
(unsigned long long) xe.bse,
291
(unsigned long long) xe.len);
290
int is_grldr_mbr(char* buf)
294
static int is_grldr_mbr(unsigned char* buf)
297
301
while ((i>n) && (buf[i]==0))
299
return (! strcmp(&buf[i-n+1],"Missing MBR-helper."));
303
return (! memcmp(&buf[i-n+1],"Missing MBR-helper.", sizeof("Missing MBR-helper.")));
302
int install(char* fn)
306
static int install(char* fn)
305
char prev_mbr[sizeof(grub_mbr)];
308
int hd = -1,nn,fs,slen;
309
unsigned char prev_mbr[sizeof(grub_mbr)];
306
310
unsigned long ssec;
331
if (nn<sizeof(grub_mbr))
335
if (nn<(int)sizeof(grub_mbr))
333
337
print_apperr("The input file is too short");
337
if (valueat(grub_mbr[0x1FFC],0,unsigned long)!=0xAA555247)
341
if (get32(&grub_mbr[0x1FFC],0)!=0xAA555247)
339
343
print_apperr("Invalid input file");
343
r2=valueat(grub_mbr[0x1FFA],0,unsigned short);
347
r2=get16(&grub_mbr[0x1FFA],0);
359
unsigned short ofs,len;
361
365
// Patching the FAT32 boot sector
362
ofs=valueat(grub_mbr,0x400+0x1EC,unsigned short) & 0x7FF;
363
strcpy(&grub_mbr[0x400+ofs],boot_file_83);
366
ofs=get16(&grub_mbr,0x400+0x1EC) & 0x7FF;
367
strcpy((char *) &grub_mbr[0x400+ofs],boot_file_83);
365
valueat(grub_mbr,0x400+0x1EA,unsigned short)=load_seg;
369
set16(&grub_mbr,0x400+0x1EA,load_seg);
367
371
// Patching the FAT12/FAT16 boot sector
368
ofs=valueat(grub_mbr,0x600+0x1EC,unsigned short) & 0x7FF;
369
strcpy(&grub_mbr[0x600+ofs],boot_file_83);
372
ofs=get16(&grub_mbr,0x600+0x1EC) & 0x7FF;
373
strcpy((char *) &grub_mbr[0x600+ofs],boot_file_83);
371
valueat(grub_mbr,0x600+0x1EA,unsigned short)=load_seg;
375
set16(&grub_mbr,0x600+0x1EA,load_seg);
373
377
// Patching the EXT2 boot sector
374
ofs=valueat(grub_mbr,0x800+0x1EE,unsigned short) & 0x7FF;
375
strcpy(&grub_mbr[0x800+ofs],boot_file);
378
ofs=get16(grub_mbr,0x800+0x1EE) & 0x7FF;
379
strcpy((char *) &grub_mbr[0x800+ofs],boot_file);
377
381
// Patching the NTFS sector
378
ofs=valueat(grub_mbr,0xA00+0x1EC,unsigned short) & 0x7FF;
379
strcpy(&grub_mbr[0xA00+ofs],boot_file);
382
ofs=get16(grub_mbr,0xA00+0x1EC) & 0x7FF;
383
strcpy((char *) &grub_mbr[0xA00+ofs],boot_file);
381
valueat(grub_mbr,0xA00+0x1EA,unsigned short)=load_seg;
385
set16(grub_mbr,0xA00+0x1EA,load_seg);
383
387
if (afg & AFG_VERBOSE)
417
421
memset(&grub_mbr[512],0,512);
418
valueat(grub_mbr,2,unsigned char)=gfg;
419
valueat(grub_mbr,3,unsigned char)=time_out;
420
valueat(grub_mbr,4,unsigned short)=hot_key;
421
valueat(grub_mbr,6,unsigned char)=def_drive;
422
valueat(grub_mbr,7,unsigned char)=def_part;
423
grub_mbr[3]=time_out;
424
set16(&grub_mbr,4,hot_key);
425
grub_mbr[6] = def_drive;
426
grub_mbr[7] = def_part;
423
427
if ((key_name==NULL) && (hot_key==0x3920))
424
428
key_name="SPACE";
426
strcpy(&grub_mbr[0x1fec],key_name);
430
strcpy((char *) &grub_mbr[0x1fec],key_name);
428
432
hd=open(fn,O_RDWR | O_BINARY,S_IREAD | S_IWRITE);
457
461
if (afg & AFG_VERBOSE)
458
fprintf(stderr,"Part Fs: %02X (%s)\nPart Leng: %u\n",xe.dfs,dfs2str(xe.dfs),xe.len);
462
fprintf(stderr,"Part Fs: %02X (%s)\nPart Leng: %llu\n",xe.dfs,dfs2str(xe.dfs),
463
(unsigned long long) xe.len);
463
468
if (afg & AFG_VERBOSE)
464
fprintf(stderr,"Start sector: %u\n",ssec);
469
fprintf(stderr,"Start sector: %llu\n", (unsigned long long) ssec);
465
470
if ((ssec) && (go_sect(hd,ssec)))
467
472
print_apperr("Can\'t seek to the start sector");
512
517
unsigned long ofs;
518
unsigned char bs[1024];
516
521
for (n=0x1BE;n<0x1FE;n+=16)
517
522
if (prev_mbr[n+4])
519
if (ofs>valueat(prev_mbr[n],8,unsigned long))
520
ofs=valueat(prev_mbr[n],8,unsigned long);
524
if (ofs>get32(&prev_mbr[n],8))
525
ofs=get32(&prev_mbr[n],8);
522
527
if (ofs<(sizeof(prev_mbr)>>9))
550
555
memcpy(&grub_mbr[0xB],&bs[0xB],sln);
551
valueat(grub_mbr[0],0x1C,unsigned long)=0;
552
valueat(grub_mbr[0],0xE,unsigned short)+=ofs;
556
set32(&grub_mbr[0],0x1C,0);
557
set16(&grub_mbr[0],0xE,get16(&grub_mbr[0],0xE) + ofs);
555
560
else if (fs==FST_NTFS)
603
if (strncmp(&prev_mbr[1024+3],"GRLDR",5))
608
if (memcmp(&prev_mbr[1024+3],"GRLDR",5))
605
610
print_apperr("GRLDR is not installed");
609
if (valueat(prev_mbr,512+510,unsigned short)!=0xAA55)
614
if (get16(prev_mbr,512+510)!=0xAA55)
611
616
print_apperr("No previous saved MBR");
644
if ((nn<512) || (nn & 0x1FF!=0) ||
645
(fs!=FST_EXT2) && (valueat(grub_mbr,510,unsigned short)!=0xAA55))
649
if ((nn<512) || ((nn & 0x1FF)!=0) ||
650
((fs!=FST_EXT2) && (get16(grub_mbr,510)!=0xAA55)))
647
652
print_apperr("Invalid restore file");
710
715
else if (fs==FST_EXT2)
712
memcpy(grub_mbr,&grub_mbr[0x800],slen);
717
memcpy(&grub_mbr,&grub_mbr[0x800],slen);
713
718
grub_mbr[0x25]=part_num;
714
719
if (afg & AFG_LBA_MODE)
715
720
grub_mbr[2]=0x42;
716
721
else if (afg & AFG_CHS_MODE)
719
valueat(grub_mbr,0x18,unsigned short)=def_spt;
724
set16(&grub_mbr,0x18,def_spt);
720
725
else if ((afg & AFG_IS_FLOPPY)==0)
721
valueat(grub_mbr,0x18,unsigned short)=63;
726
set16(&grub_mbr,0x18,63);
723
valueat(grub_mbr,0x1A,unsigned short)=def_hds;
728
set16(&grub_mbr,0x1A,def_hds);
724
729
else if ((afg & AFG_IS_FLOPPY)==0)
725
valueat(grub_mbr,0x1A,unsigned short)=255;
730
set16(&grub_mbr,0x1A,255);
727
valueat(grub_mbr,0x20,unsigned long)=def_tsc;
728
valueat(grub_mbr,0x1C,unsigned long)=ssec;
732
set32(&grub_mbr,0x20,def_tsc);
733
set32(&grub_mbr,0x1C,ssec);
730
735
if (prev_mbr[1024+0x4C]) // s_rev_level
731
valueat(grub_mbr,0x26,unsigned short)=valueat(prev_mbr[1024],0x58,unsigned short);
736
set16(&grub_mbr,0x26,get16(&prev_mbr[1024],0x58));
733
valueat(grub_mbr,0x26,unsigned short)=0x80;
738
set16(&grub_mbr,0x26,0x80);
734
739
// s_inodes_per_group
735
valueat(grub_mbr,0x28,unsigned long)=valueat(prev_mbr[1024],0x28,unsigned long);
740
set32(&grub_mbr,0x28,get32(&prev_mbr[1024],0x28));
736
741
// s_first_data_block+1
737
valueat(grub_mbr,0x2C,unsigned long)=valueat(prev_mbr[1024],0x14,unsigned long)+1;
742
set32(&grub_mbr,0x2C,get32(&prev_mbr[1024],0x14)+1);
762
767
else if (fs==FST_FAT16)
764
769
memcpy(&grub_mbr[0xB],&prev_mbr[0xB],0x3E - 0xB);
765
valueat(grub_mbr,0x1C,unsigned long)=ssec;
770
set32(grub_mbr,0x1C,ssec);
767
772
else if (fs==FST_FAT32)
769
774
memcpy(&grub_mbr[0xB],&prev_mbr[0xB],0x5A - 0xB);
770
valueat(grub_mbr,0x1C,unsigned long)=ssec;
775
set32(grub_mbr,0x1C,ssec);
772
777
else if (fs==FST_NTFS)
774
779
memcpy(&grub_mbr[0xB],&prev_mbr[0xB],0x54 - 0xB);
775
valueat(grub_mbr,0x1C,unsigned long)=ssec;
780
set32(grub_mbr,0x1C,ssec);
778
783
if (! (afg & AFG_READ_ONLY))