⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 grub-winme-c-1129

📁 grub_for_dos-0.4.2
💻
字号:
diff -NaurbB -X ../patch/grub.skip grub-0.97.org/stage2/builtins.c grub-0.97/stage2/builtins.c--- grub-0.97.org/stage2/builtins.c	Sat Dec 10 03:57:03 2005+++ grub-0.97/stage2/builtins.c	Sat Dec 10 06:59:09 2005@@ -327,6 +327,186 @@   "Print the blocklist notation of the file FILE." }; +// The following routines are used to decompress IO.SYS from WinME++static int ibuf_pos;+static char *ibuf_ptr,*obuf_ptr;+static unsigned short ibuf_tab[16];++void ibuf_init(char* buf);+unsigned short ibuf_read(int nbits);+int expand_block(int nsec);+long expand_file(char* src,char* dst);++void ibuf_init(char* buf)+{+  int i;++  ibuf_ptr=buf;+  ibuf_pos=0;++  // ibuf_tab[i]=(1<<(i+1))-1+  ibuf_tab[0]=1;+  for (i=1;i<16;i++)+    ibuf_tab[i]=ibuf_tab[i-1]*2+1;+}++unsigned short ibuf_read(int nbits)+{+  unsigned short res;++  res=(unsigned short)((*((unsigned long*)ibuf_ptr)>>ibuf_pos) & ibuf_tab[nbits-1]);+  ibuf_pos+=nbits;+  if (ibuf_pos>=8)+    {+      ibuf_ptr+=(ibuf_pos>>3);+      ibuf_pos&=7;+    }+  return res;+}++#define obuf_init(buf)		obuf_ptr=buf+#define obuf_putc(ch)		*(obuf_ptr++)=ch+#define obuf_copy(ofs,len)	do { for (;len>0;obuf_ptr++,len--) *(obuf_ptr)=*(obuf_ptr-ofs); } while (0)+// Don't use memcpy, otherwise we could be screwed !++int expand_block(int nsec)+{+  while (nsec>0)+    {+      int cnt;++      cnt=0x200;+      while (1)+        {+          int flg,ofs,bts,bse,del,len;++          flg=ibuf_read(2);++          if (flg==0) ofs=ibuf_read(6); else+            if (flg==3)+              {+                if (ibuf_read(1))+                  {+                    ofs=ibuf_read(12)+0x140;+                    if (ofs==0x113F)+                      break;+                  }+                else+                  ofs=ibuf_read(8)+0x40;+              } else+                {+                  char ch;++                  cnt--;+                  if (cnt<0)+                    {+                      grub_putstr("Data corrupted");+                      return 1;+                    }+                  ch=ibuf_read(7);+                  if (flg & 1)+                    ch|=0x80;+                  obuf_putc(ch);+                  continue;+                }+          if (ofs==0)+            {+              grub_putstr("Data corrupted");+              return 1;+            }+          bse=2;+          del=0;+          for (bts=0;bts<9;bts++)+            {+              if (ibuf_read(1))+                break;+              bse+=del+1;+              del=del*2+1;+            }+          if (bts==9)+            {+              grub_putstr("Data corrupted");+              return 1;+            }+          len=(bts)?bse+ibuf_read(bts):bse;+          if ((cnt=cnt-len)<0)+            {+              grub_putstr("Data corrupted");+              return 1;+            }+          obuf_copy(ofs,len);+        }+      nsec--;+      if ((cnt) && (nsec))+        {+          grub_putstr("Data corrupted");+          return 1;+        }+    }+  return 0;+}++long expand_file(char* src,char* dst)+{+  ibuf_init(src);+  obuf_init(dst);++  if (ibuf_read(16)!=0x4D43)+    {+      grub_putstr("First CM signature not found");+      return -1;+    }+  while (1)+    {+      unsigned short flg,len;++      flg=ibuf_read(8);+      len=ibuf_read(16);+      if (len==0)+        {+          int n;++          n=(ibuf_ptr-src) & 0xF;+          if ((n) || (ibuf_pos))+            {+              ibuf_ptr+=16-n;+              ibuf_pos=0;+            }+          if (ibuf_read(16)!=0x4D43)+            {+              grub_putstr("Second CM signature not found");+              return -1;+            }+          return obuf_ptr-dst;+        }+      if (flg==0)+        {+          memcpy(obuf_ptr,ibuf_ptr,len);+          ibuf_ptr+=len;+          obuf_ptr+=len;+        }+      else+        {+          char* save_ptr;+          unsigned short sec;++          sec=(ibuf_read(16)+511)>>9;+          save_ptr=ibuf_ptr;+          if (ibuf_read(16)!=0x5344)+            {+              grub_putstr("0x5344 signature not found");+              return -1;+            }+          ibuf_read(16);+          if (expand_block(sec))+            return -1;+          ibuf_ptr=save_ptr+len;+          ibuf_pos=0;+        }+    }+}+ /* boot */ static int boot_func (char *arg, int flags)@@ -550,6 +730,24 @@ 		    return 1; 		  } 		grub_close ();++		// Not a very neat way to test WinME, works anyway+		if ((*(unsigned short*)0x110000==0x4D43) &&+		    ((*(char*)0x110002==0) || (*(unsigned short*)0x110000==0x4D43)) &&+		    (chainloader_skip_length==0x800))+		  {+		    unsigned long len;+		    len=expand_file((char*)0x110000,(char*)0x1B0000);+		    if (len==0)+		      {+		        kernel_type = KERNEL_TYPE_NONE;+			if (errnum ==ERR_NONE)+			  errnum = ERR_EXEC_FORMAT;+			return 1;+		      }+		    grub_memmove((char*)0x110000,(char*)0x1B0000,len);+		    chainloader_load_length=read_length=len;+		  } 	    } 		 		if (chainloader_load_length == -1 || chainloader_load_length > read_length)@@ -989,7 +1187,7 @@     }   else   if (*(short *)BOOTSEC_LOCATION == 0x5A4D && filemax > 0x10000 &&-       (*((unsigned short *) (BOOTSEC_LOCATION + BOOTSEC_SIG_OFFSET)) == 0 /* != BOOTSEC_SIGNATURE */ && (*(long *)(BOOTSEC_LOCATION + 0xA2)) == 0 ))+       (*((unsigned short *) (BOOTSEC_LOCATION + BOOTSEC_SIG_OFFSET)) == 0)) // /* != BOOTSEC_SIGNATURE */ && (*(long *)(BOOTSEC_LOCATION + 0xA2)) == 0 ))     {        int err;@@ -1026,11 +1224,27 @@ 		chainloader_load_length = filemax; 	if (chainloader_skip_length == 0) 		chainloader_skip_length = 0x0800;++	// Input parameter for SYSINIT+	// BX,AX: Start sector for the data area of FAT. It doesn't needs to+	//        be set. However, we should at least clear BX, otherwise,+	//        it would have some minor problem when booting WinME.+	// DI:    Length of the boot code, don't need to be set.+	// BP:    0x7C00, boot sector pointer, don't need to be set.+	// DH:    Media ID (BS[0x15]) , 0xF0 for floppy, 0xF8 for harddisk+	// DL:    Drive number (BS[0x40] for FAT32)+ 	if (! chainloader_edx_set) 	{-		chainloader_edx = current_drive | ((current_partition >> 8) & 0xFF00);+		//chainloader_edx = current_drive | ((current_partition >> 8) & 0xFF00);+		chainloader_edx = current_drive | 0xF000 | ((current_drive & 0x80)<<4); 		chainloader_edx_set = 1; 	}+	if (! chainloader_ebx_set)+	{+		chainloader_ebx = 0;+		chainloader_ebx_set = 1;+	} 	     	grub_printf("Will boot MS-DOS 7.x from drive=0x%x\n", (chainloader_edx & 0x80));       }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -