~ubuntu-branches/ubuntu/trusty/grub2/trusty

« back to all changes in this revision

Viewing changes to debian/grub-extras/ntldr-img/grubinst.c

  • Committer: Package Import Robot
  • Author(s): Colin Watson
  • Date: 2014-01-16 15:18:04 UTC
  • mfrom: (17.6.38 experimental)
  • Revision ID: package-import@ubuntu.com-20140116151804-3foouk7fpqcq3sxx
Tags: 2.02~beta2-2
* Convert patch handling to git-dpm.
* Add bi-endian support to ELF parser (Tomohiro B Berry).
* Adjust restore_mkdevicemap.patch to mark get_kfreebsd_version as static,
  to appease "gcc -Werror=missing-prototypes".
* Cherry-pick from upstream:
  - Change grub-macbless' manual page section to 8.
* Install grub-glue-efi, grub-macbless, grub-render-label, and
  grub-syslinux2cfg.
* grub-shell: Pass -no-pad to xorriso when building floppy images.

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
#include <fcntl.h>
24
24
#include <sys/stat.h>
25
25
#include <errno.h>
 
26
#include <unistd.h>
26
27
 
27
28
#ifndef WIN32
28
29
 
63
64
#define print_apperr(a)         { fprintf(stderr,APP_NAME "%s\n",a); print_pause; }
64
65
#define print_syserr(a)         { perror(APP_NAME a); print_pause; }
65
66
 
66
 
void help(void)
 
67
static void help(void)
67
68
{
68
69
  fputs("Usage:\n"
69
70
        "\tgrubinst  [OPTIONS]  DEVICE_OR_FILE\n\n"
146
147
 
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;
151
154
 
152
155
static char fn_buf[24];
153
156
 
154
 
char* get_disk_name(int n)
 
157
static char* get_disk_name(int n)
155
158
{
156
159
#if defined(WIN32)
157
160
  sprintf(fn_buf,"\\\\.\\PhysicalDrive%d",n);
166
169
  return fn_buf;
167
170
}
168
171
 
169
 
char* get_flop_name(int n)
 
172
static char* get_flop_name(int n)
170
173
{
171
174
#if defined(WIN32)
172
175
  if (n>1)
184
187
  return fn_buf;
185
188
}
186
189
 
187
 
char* parse_fname(char* fn)
 
190
static char* parse_fname(char* fn)
188
191
{
189
192
  if ((afg & AFG_OUTPUT) && (fn[0]=='('))
190
193
    {
227
230
  return fn;
228
231
}
229
232
 
230
 
char* str_upcase(char* str)
 
233
static char* str_upcase(char* str)
231
234
{
232
235
  int i;
233
236
 
238
241
  return str;
239
242
}
240
243
 
241
 
char* str_lowcase(char* str)
 
244
static char* str_lowcase(char* str)
242
245
{
243
246
  int i;
244
247
 
249
252
  return str;
250
253
}
251
254
 
252
 
int SetBootFile(char* fn)
 
255
static int SetBootFile(char* fn)
253
256
{
254
257
  char* pc;
255
258
 
275
278
  return 0;
276
279
}
277
280
 
278
 
int chk_mbr(unsigned char* buf);
279
 
 
280
 
void list(int hd)
 
281
static void list(int hd)
281
282
{
282
283
  xde_t xe;
283
284
 
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);
288
292
}
289
293
 
290
 
int is_grldr_mbr(char* buf)
 
294
static int is_grldr_mbr(unsigned char* buf)
291
295
{
292
296
  int i,n;
293
297
 
296
300
 
297
301
  while ((i>n) && (buf[i]==0))
298
302
    i--;
299
 
  return (! strcmp(&buf[i-n+1],"Missing MBR-helper."));
 
303
  return (! memcmp(&buf[i-n+1],"Missing MBR-helper.", sizeof("Missing MBR-helper.")));
300
304
}
301
305
 
302
 
int install(char* fn)
 
306
static int install(char* fn)
303
307
{
304
 
  int hd,nn,fs,slen;
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;
307
311
 
308
312
  if (fn==NULL)
320
324
          print_syserr("open");
321
325
          return errno;
322
326
        }
323
 
      r1=valueat(grub_mbr[0x1FFA],0,unsigned short);
 
327
      r1=get16(&grub_mbr[0x1FFA],0);
324
328
      nn=read(hd,grub_mbr,sizeof(grub_mbr));
325
329
      if (nn==-1)
326
330
        {
328
332
          close(hd);
329
333
          return errno;
330
334
        }
331
 
      if (nn<sizeof(grub_mbr))
 
335
      if (nn<(int)sizeof(grub_mbr))
332
336
        {
333
337
          print_apperr("The input file is too short");
334
338
          close(hd);
335
339
          return 1;
336
340
        }
337
 
      if (valueat(grub_mbr[0x1FFC],0,unsigned long)!=0xAA555247)
 
341
      if (get32(&grub_mbr[0x1FFC],0)!=0xAA555247)
338
342
        {
339
343
          print_apperr("Invalid input file");
340
344
          close(hd);
341
345
          return 1;
342
346
        }
343
 
      r2=valueat(grub_mbr[0x1FFA],0,unsigned short);
 
347
      r2=get16(&grub_mbr[0x1FFA],0);
344
348
      if (r1!=r2)
345
349
        {
346
350
          char buf[80];
356
360
 
357
361
  if (boot_file)
358
362
    {
359
 
      unsigned short ofs,len;
 
363
      unsigned short ofs;
360
364
 
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);
364
368
      if (load_seg)
365
 
        valueat(grub_mbr,0x400+0x1EA,unsigned short)=load_seg;
 
369
        set16(&grub_mbr,0x400+0x1EA,load_seg);
366
370
 
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);
370
374
      if (load_seg)
371
 
        valueat(grub_mbr,0x600+0x1EA,unsigned short)=load_seg;
 
375
        set16(&grub_mbr,0x600+0x1EA,load_seg);
372
376
 
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);
376
380
 
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);
380
384
      if (load_seg)
381
 
        valueat(grub_mbr,0xA00+0x1EA,unsigned short)=load_seg;
 
385
        set16(grub_mbr,0xA00+0x1EA,load_seg);
382
386
 
383
387
      if (afg & AFG_VERBOSE)
384
388
        {
415
419
    }
416
420
 
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;
 
422
  grub_mbr[2] = gfg;
 
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";
425
429
  if (key_name)
426
 
    strcpy(&grub_mbr[0x1fec],key_name);
 
430
    strcpy((char *) &grub_mbr[0x1fec],key_name);
427
431
 
428
432
  hd=open(fn,O_RDWR | O_BINARY,S_IREAD | S_IWRITE);
429
433
  if (hd==-1)
455
459
            }
456
460
          ssec=xe.bse;
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);
459
464
        }
460
465
    }
461
466
  else
462
467
    ssec=0;
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)))
466
471
    {
467
472
      print_apperr("Can\'t seek to the start sector");
475
480
      close(hd);
476
481
      return errno;
477
482
    }
478
 
  if (nn<sizeof(prev_mbr))
 
483
  if (nn<(int)sizeof(prev_mbr))
479
484
    {
480
485
      print_apperr("The input file is too short");
481
486
      close(hd);
510
515
    {
511
516
      int n,nfs,sln;
512
517
      unsigned long ofs;
513
 
      char bs[1024];
 
518
      unsigned char bs[1024];
514
519
 
515
520
      ofs=0xFFFFFFFF;
516
521
      for (n=0x1BE;n<0x1FE;n+=16)
517
522
        if (prev_mbr[n+4])
518
523
          {
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);
521
526
          }
522
527
      if (ofs<(sizeof(prev_mbr)>>9))
523
528
        {
548
553
      if (sln)
549
554
        {
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);
553
558
        }
554
559
    }
555
560
  else if (fs==FST_NTFS)
600
605
          close(hd);
601
606
          return 1;
602
607
        }
603
 
      if (strncmp(&prev_mbr[1024+3],"GRLDR",5))
 
608
      if (memcmp(&prev_mbr[1024+3],"GRLDR",5))
604
609
        {
605
610
          print_apperr("GRLDR is not installed");
606
611
          close(hd);
607
612
          return 1;
608
613
        }
609
 
      if (valueat(prev_mbr,512+510,unsigned short)!=0xAA55)
 
614
      if (get16(prev_mbr,512+510)!=0xAA55)
610
615
        {
611
616
          print_apperr("No previous saved MBR");
612
617
          close(hd);
641
646
              close(h2);
642
647
              return errno;
643
648
            }
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)))
646
651
            {
647
652
              print_apperr("Invalid restore file");
648
653
              close(hd);
709
714
            }
710
715
          else if (fs==FST_EXT2)
711
716
            {
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)
717
722
                grub_mbr[2]=0x2;
718
723
              if (def_spt!=-1)
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);
722
727
              if (def_hds!=-1)
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);
726
731
              if (def_tsc!=-1)
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);
729
734
              // s_inode_size
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));
732
737
              else
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);
738
743
            }
739
744
          else
740
745
            {
762
767
      else if (fs==FST_FAT16)
763
768
        {
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);
766
771
        }
767
772
      else if (fs==FST_FAT32)
768
773
        {
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);
771
776
        }
772
777
      else if (fs==FST_NTFS)
773
778
        {
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);
776
781
        }
777
782
    }
778
783
  if (! (afg & AFG_READ_ONLY))