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

📄 disk_io.c

📁 grub4dos-0.4.4-2008- 08-src.zip
💻 C
📖 第 1 页 / 共 4 页
字号:
intdevwrite (unsigned long sector, unsigned long sector_count, char *buf){#if defined(GRUB_UTIL) && defined(__linux__)  if (current_partition != 0xFFFFFF      && is_disk_device (device_map, current_drive))    {      /* If the grub shell is running under Linux and the user wants to	 embed a Stage 1.5 into a partition instead of a MBR, use system	 calls directly instead of biosdisk, because of the bug in	 Linux. *sigh*  */      return write_to_partition (device_map, current_drive, current_partition, sector, sector_count, buf);    }  else#endif /* GRUB_UTIL && __linux__ */    {      //unsigned long i;      for (i = 0; i < sector_count; i++)	{	  if (! rawwrite (current_drive, part_start + sector + i, buf + (i << SECTOR_BITS)))	      return 0;	}      return 1;    }}#endif /* ! STAGE1_5 */#ifndef STAGE1_5intset_bootdev (int hdbias){  int j;  /* Copy the boot partition information to 0x7be-0x7fd for chain-loading.  */  if ((saved_drive & 0x80) && cur_part_addr)    {      if (rawread (saved_drive, cur_part_offset, 0, SECTOR_SIZE, (char *) SCRATCHADDR))	{	  char *dst, *src;	  /* Need only the partition table.	     XXX: We cannot use grub_memmove because BOOT_PART_TABLE	     (0x07be) is less than 0x1000.  */	  dst = (char *) BOOT_PART_TABLE;	  src = (char *) SCRATCHADDR + BOOTSEC_PART_OFFSET;	  while (dst < (char *) BOOT_PART_TABLE + BOOTSEC_PART_LENGTH)	    *dst++ = *src++;	  /* Clear the active flag of all partitions.  */	  for (i = 0; i < 4; i++)	    PC_SLICE_FLAG (BOOT_PART_TABLE - BOOTSEC_PART_OFFSET, i) = 0;	  /* Set the active flag of the booted partition.  */	  *((unsigned char *) cur_part_addr) = PC_SLICE_FLAG_BOOTABLE;	  boot_part_addr = cur_part_addr;	}      else      {	return 0;      }    }  /*   *  Set BSD boot device.   */  i = (saved_partition >> 16) + 2;  if (saved_partition == 0xFFFFFF)    i = 1;  else if ((saved_partition >> 16) == 0xFF)    i = 0;  /* FIXME: extremely evil hack!!! */  j = 2;  if (saved_drive & 0x80)    j = bsd_evil_hack;  return MAKEBOOTDEV (j, (i >> 4), (i & 0xF), ((saved_drive - hdbias) & 0x7F), ((saved_partition >> 8) & 0xFF));}#endif /* STAGE1_5 */#ifndef STAGE1_5/* *  This prints the filesystem type or gives relevant information. */voidprint_fsys_type (void){  if (! do_completion)    {      printf (" Filesystem type ");      if (fsys_type != NUM_FSYS)	printf ("is %s, ", fsys_table[fsys_type].name);      else	printf ("unknown, ");      if (current_partition == 0xFFFFFF)	printf ("using whole disk\n");      else	printf ("partition type 0x%02X\n", current_slice & 0xFF);    }}#endif /* ! STAGE1_5 */  /* Get next BSD partition in current PC slice.  */static intnext_bsd_partition (/*unsigned long drive, unsigned long *partition, int *type, unsigned long *start, unsigned long *len, char *buf*/void){//    int i;      bsd_part_no = (*next_partition_partition & 0xFF00) >> 8;#ifndef STAGE1_5//if (debug == -2) grub_printf ("next_bsd_partition: 001\n");#endif      /* If this is the first time...  */      if (bsd_part_no == 0xFF)	{	  /* Check if the BSD label is within current PC slice.  */	  if (*next_partition_len < BSD_LABEL_SECTOR + 1)	    {	      errnum = ERR_BAD_PART_TABLE;	      return 0;	    }#ifndef STAGE1_5//if (debug == -2) grub_printf ("next_bsd_partition: 002\n");#endif	  /* Read the BSD label.  */	  if (! rawread (next_partition_drive, *next_partition_start + BSD_LABEL_SECTOR,			 0, SECTOR_SIZE, next_partition_buf))	    return 0;#ifndef STAGE1_5//if (debug == -2) grub_printf ("next_bsd_partition: 003\n");#endif	  /* Check if it is valid.  */	  if (! BSD_LABEL_CHECK_MAG (next_partition_buf))	    {	      errnum = ERR_BAD_PART_TABLE;	      return 0;	    }	  bsd_part_no = -1;	}#ifndef STAGE1_5//if (debug == -2) grub_printf ("next_bsd_partition: 004\n");#endif      /* Search next valid BSD partition.  */      if (BSD_LABEL_NPARTS (next_partition_buf) <= BSD_LABEL_NPARTS_MAX)      for (i = bsd_part_no + 1; i < BSD_LABEL_NPARTS (next_partition_buf); i++)	{	  if (BSD_PART_TYPE (next_partition_buf, i))	    {	      /* Note that *TYPE and *PARTITION were set		 for current PC slice.  */	      *next_partition_type = (BSD_PART_TYPE (next_partition_buf, i) << 8) | (*next_partition_type & 0xFF);	      *next_partition_start = BSD_PART_START (next_partition_buf, i);	      *next_partition_len = BSD_PART_LENGTH (next_partition_buf, i);	      *next_partition_partition = (*next_partition_partition & 0xFF00FF) | (i << 8);#ifndef STAGE1_5	      /* XXX */	      if ((next_partition_drive & 0x80) && BSD_LABEL_DTYPE (next_partition_buf) == DTYPE_SCSI)		bsd_evil_hack = 4;#endif /* ! STAGE1_5 */	      return 1;	    }	}#ifndef STAGE1_5//if (debug == -2) grub_printf ("next_bsd_partition: 005\n");#endif      errnum = ERR_NO_PART;      return 0;}  /* Get next PC slice. Be careful of that this function may return     an empty PC slice (i.e. a partition whose type is zero) as well.  */static intnext_pc_slice (void){redo:#ifndef STAGE1_5//if (debug == -2) grub_printf ("next_pc_slice: 001\n");#endif      pc_slice_no = (*next_partition_partition & 0xFF0000) >> 16;      /* If this is the first time...  */      if (pc_slice_no == 0xFF)	{	  *next_partition_offset = 0;	  *next_partition_ext_offset = 0;	  *next_partition_entry = -1;	  pc_slice_no = -1;	}#ifndef STAGE1_5//if (debug == -2) grub_printf ("next_pc_slice: 002\n");#endif      /* Read the MBR or the boot sector of the extended partition.  */      if (! rawread (next_partition_drive, *next_partition_offset, 0, SECTOR_SIZE, next_partition_buf))	return 0;      /* Check if it is valid.  */      if (! PC_MBR_CHECK_SIG (next_partition_buf))	{	  errnum = ERR_BAD_PART_TABLE;	  return 0;	}next_entry:#ifndef STAGE1_5//if (debug == -2) grub_printf ("next_pc_slice: 003\n");#endif      /* Increase the entry number.  */      (*next_partition_entry)++;      /* If this is out of current partition table...  */      if (*next_partition_entry == PC_SLICE_MAX)	{//	  int i;	  /* Search the first extended partition in current table.  */	  for (i = 0; i < PC_SLICE_MAX; i++)	    {	      if (IS_PC_SLICE_TYPE_EXTENDED (PC_SLICE_TYPE (next_partition_buf, i)))		{		  /* Found. Set the new offset and the entry number,		     and restart this function.  */		  *next_partition_offset = *next_partition_ext_offset + PC_SLICE_START (next_partition_buf, i);		  if (! *next_partition_ext_offset)		    *next_partition_ext_offset = *next_partition_offset;		  *next_partition_entry = -1;#ifndef STAGE1_5//if (debug == -2) grub_printf ("next_pc_slice: recursive call\n");#endif#if 0		  return next_pc_slice ();	/* FIXME: Recursive!!!! */#else		  goto redo;#endif		}	    }#ifndef STAGE1_5//if (debug == -2) grub_printf ("next_pc_slice: return error\n");#endif	  errnum = ERR_NO_PART;	  return 0;	}      *next_partition_type = PC_SLICE_TYPE (next_partition_buf, *next_partition_entry);      *next_partition_start = *next_partition_offset + PC_SLICE_START (next_partition_buf, *next_partition_entry);      *next_partition_len = PC_SLICE_LENGTH (next_partition_buf, *next_partition_entry);      /* The calculation of a PC slice number is complicated, because of	 the rather odd definition of extended partitions. Even worse,	 there is no guarantee that this is consistent with every	 operating systems. Uggh.  */      if (((int)pc_slice_no) >= PC_SLICE_MAX - 1	/* if it is a logical partition */	  && (PC_SLICE_ENTRY_IS_EMPTY (next_partition_buf, *next_partition_entry))) /* ignore the garbage entry(typically all bytes are 0xF6). */	goto next_entry;#if 1      /* disable partition id 00. */      if (((int)pc_slice_no) >= PC_SLICE_MAX - 1	/* if it is a logical partition */	  && *next_partition_type == PC_SLICE_TYPE_NONE)	/* ignore the partition with id=00. */	goto next_entry;#else      /* enable partition id 00. */#endif      if (((int)pc_slice_no) < PC_SLICE_MAX - 1	  || ! IS_PC_SLICE_TYPE_EXTENDED (*next_partition_type))	pc_slice_no++;#ifndef STAGE1_5//if (debug == -2) grub_printf ("next_pc_slice: return success\n");#endif      *next_partition_partition = (pc_slice_no << 16) | 0xFFFF;      return 1;}/* Get the information on next partition on the drive DRIVE.   The caller must not modify the contents of the arguments when   iterating this function. The partition representation in GRUB will   be stored in *PARTITION. Likewise, the partition type in *TYPE, the   start sector in *START, the length in *LEN, the offset of the   partition table in *OFFSET, the entry number in the table in *ENTRY,   the offset of the extended partition in *EXT_OFFSET.   BUF is used to store a MBR, the boot sector of a partition, or   a BSD label sector, and it must be at least 512 bytes length.   When calling this function first, *PARTITION must be initialized to   0xFFFFFF. The return value is zero if fails, otherwise non-zero.  */intnext_partition (/*unsigned long drive, unsigned long dest,		unsigned long *partition, int *type,		unsigned long *start, unsigned long *len,		unsigned long *offset, int *entry,		unsigned long *ext_offset, char *buf*/void){  /* Start the body of this function.  */#ifndef STAGE1_5  if ((current_drive == NETWORK_DRIVE) || (current_drive == PXE_DRIVE))    return 0;#endif  /* If previous partition is a BSD partition or a PC slice which     contains BSD partitions...  */  if ((*next_partition_partition != 0xFFFFFF && IS_PC_SLICE_TYPE_BSD (*next_partition_type & 0xff))      || ! (next_partition_drive & 0x80))    {#ifndef STAGE1_5//if (debug == -2) grub_printf ("next_partition: bsd check begin\n");#endif      if (*next_partition_type == PC_SLICE_TYPE_NONE)	*next_partition_type = PC_SLICE_TYPE_FREEBSD;      /* Get next BSD partition, if any.  */      if (next_bsd_partition (/*next_partition_drive, next_partition_partition, next_partition_type, next_partition_start, next_partition_len, next_partition_buf*/))	return 1;      /* If the destination partition is a BSD partition and current	 BSD partition has any error, abort the operation.  */      if ((next_partition_dest & 0xFF00) != 0xFF00	  && ((next_partition_dest & 0xFF0000) == 0xFF0000	      || (next_partition_dest & 0xFF0000) == (*next_partition_partition & 0xFF0000)))	return 0;      /* Ignore the error.  */      errnum = ERR_NONE;    }#ifndef STAGE1_5//if (debug == -2) grub_printf ("next_partition: next_pc_slice begin\n");#endif  return next_pc_slice ();}static voidattempt_mount (void){#ifndef STAGE1_5  for (fsys_type = 0; fsys_type < NUM_FSYS; fsys_type++)  {//    if (fsys_type >= 4) continue;    if (errnum = 0, ((fsys_table[fsys_type].mount_func) ()))      break;  }  if (fsys_type == NUM_FSYS && errnum == ERR_NONE)    errnum = ERR_FSYS_MOUNT;#else  fsys_type = 0;  if ((*(fsys_table[fsys_type].mount_func)) () != 1)    {      fsys_type = NUM_FSYS;      errnum = ERR_FSYS_MOUNT;    }#endif}/* *  This performs a "mount" on the current device, both drive and partition *  number. */intopen_device (void){  if (open_partition ())    attempt_mount ();  if (errnum != ERR_NONE)    return 0;  return 1;}  /* For simplicity.  */static unsigned long next_part (void);static unsigned longnext_part (void){	next_partition_drive		= current_drive;	next_partition_dest		= dest_partition;	next_partition_partition	= &current_partition;	next_partition_type		= &current_slice;	next_partition_start		= &part_start;	next_partition_len		= &part_length;	next_partition_offset		= &part_offset;	next_partition_entry		= &entry;	next_partition_ext_offset	= &ext_offset;	next_partition_buf		= mbr;	i = next_partition ();	bsd_part_no = (current_partition >> 8) & 0xFF;	pc_slice_no = current_partition >> 16;	return i;}#ifndef STAGE1_5static voidcheck_and_print_mount (void){  attempt_mount ();  if (errnum == ERR_FSYS_MOUNT)    errnum = ERR_NONE;  if (!errnum)    print_fsys_type ();  print_error ();}#endif /* ! STAGE1_5 *//* Open a partition.  */intreal_open_partition (int flags){#if defined(STAGE1_5) || defined(GRUB_UTIL)//  char mbr[SECTOR_SIZE];#endif//  int bsd_part, pc_slice;  dest_partition = current_partition;#ifndef STAGE1_5  /* network drive */  if ((current_drive == NETWORK_DRIVE) || (current_drive==PXE_DRIVE))    return 1;  if (! sane_partition ())    return 0;#endif  bsd_evil_hack = 0;  current_slice = 0;  part_start = 0;  /* Make sure that buf_geom is valid. */  if (buf_drive != current_drive)    {      if (get_diskinfo (current_drive, &buf_geom))	{	  errnum = ERR_NO_DISK;	  return 0;	}      buf_drive = current_drive;      buf_track = -1;    }  part_length = buf_geom.total_sectors;  /* If this is the whole disk, return here.  */  if (! flags && current_partition == 0xFFFFFF)    return 1;  if (flags)    dest_partition = 0xFFFFFF;  /* Initialize CURRENT_PARTITION for next_partition.  */  current_partition = 0xFFFFFF;  while (next_part ())    {#ifndef STAGE1_5    loop_start:      cur_part_offset = part_offset;      cur_part_addr = BOOT_PART_TABLE + (entry << 4);//if (debug == -2) grub_printf ("real_open_partition: outer loop: 001\n");#endif /* ! STAGE1_5 */      /* If this is a valid partition...  */      if (current_slice)	{#ifndef STAGE1_5	  /* Display partition information.  */	  if (flags && ! IS_PC_SLICE_TYPE_EXTENDED (current_slice))	    {	      if (! do_completion)		{		  if (current_drive & 0x80)		    {			int active = (PC_SLICE_FLAG (mbr, entry) == PC_SLICE_FLAG_BOOTABLE);			grub_printf ("   Partition num: %d%s, ",				 (current_partition >> 16), (active ? ", active": ""));		    }//if (debug == -2) grub_printf ("real_open_partition: outer loop: 002\n");		  if (! IS_PC_SLICE_TYPE_BSD (current_slice))		    check_and_print_mount ();		  else		    {		      int got_part = 0;		      int saved_slice = current_slice;

⌨️ 快捷键说明

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