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

📄 disk_io.c

📁 i386的bootloader源码grub
💻 C
📖 第 1 页 / 共 3 页
字号:
  #else /* ! STAGE1_5 */    if (*filename == '(')    {      if ((filename = set_device (filename)) == 0)	{	  current_drive = GRUB_INVALID_DRIVE;	  return 0;	}# ifndef NO_BLOCK_FILES      if (*filename != '/')	open_partition ();      else# endif /* ! NO_BLOCK_FILES */	open_device ();    }  else if (saved_drive != current_drive	   || saved_partition != current_partition	   || (*filename == '/' && fsys_type == NUM_FSYS)	   || buf_drive == -1)    {      current_drive = saved_drive;      current_partition = saved_partition;      /* allow for the error case of "no filesystem" after the partition         is found.  This makes block files work fine on no filesystem */# ifndef NO_BLOCK_FILES      if (*filename != '/')	open_partition ();      else# endif /* ! NO_BLOCK_FILES */	open_device ();    }  #endif /* ! STAGE1_5 */    if (errnum && (*filename == '/' || errnum != ERR_FSYS_MOUNT))    return 0;  else    errnum = 0;#ifndef STAGE1_5  if (!sane_partition ())    return 0;#endif  return filename;}#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%x\n", current_slice & 0xFF);    }}#endif /* STAGE1_5 */#ifndef STAGE1_5/* If DO_COMPLETION is true, just print NAME. Otherwise save the unique   part into UNIQUE_STRING.  */voidprint_a_completion (char *name){  /* If NAME is "." or "..", do not count it.  */  if (grub_strcmp (name, ".") == 0 || grub_strcmp (name, "..") == 0)    return;    if (do_completion)    {      char *buf = unique_string;            if (! unique)	while ((*buf++ = *name++))	  ;      else	{	  while (*buf && (*buf == *name))	    {	      buf++;	      name++;	    }	  /* mismatch, strip it.  */	  *buf = '\0';	}    }  else    grub_printf (" %s", name);    unique++;}/* *  This lists the possible completions of a device string, filename, or *  any sane combination of the two. */intprint_completions (int is_filename, int is_completion){  char *buf = (char *) COMPLETION_BUF;  char *ptr = buf;  unique_string = (char *) UNIQUE_BUF;  *unique_string = 0;  unique = 0;  do_completion = is_completion;  if (! is_filename)    {      /* Print the completions of builtin commands.  */      struct builtin **builtin;      if (! is_completion)	grub_printf (" Possible commands are:");            for (builtin = builtin_table; (*builtin); builtin++)	{	  /* If *BUILTIN cannot be run in the command-line, skip it.  */	  if (! ((*builtin)->flags & BUILTIN_CMDLINE))	    continue;	  if (substring (buf, (*builtin)->name) <= 0)	    print_a_completion ((*builtin)->name);	}      if (is_completion && *unique_string)	{	  if (unique == 1)	    {	      char *u = unique_string + grub_strlen (unique_string);	      *u++ = ' ';	      *u = 0;	    }	  	  grub_strcpy (buf, unique_string);	}      if (! is_completion)	grub_putchar ('\n');            print_error ();      do_completion = 0;      if (errnum)	return -1;      else	return unique - 1;    }  if (*buf == '/' || (ptr = set_device (buf)) || incomplete)    {      errnum = 0;      if (*buf == '(' && (incomplete || ! *ptr))	{	  if (! part_choice)	    {	      /* disk completions */	      int disk_no, i, j;	      struct geometry geom;	      if (! is_completion)		grub_printf (" Possible disks are: ");	      if (!ptr		  || *(ptr-1) != 'd'#ifdef SUPPORT_NETBOOT		  || *(ptr-2) != 'n'#endif /* SUPPORT_NETBOOT */		  || *(ptr-2) != 'c')		{		  for (i = (ptr && (*(ptr-1) == 'd' && *(ptr-2) == 'h') ? 1:0);		       i < (ptr && (*(ptr-1) == 'd' && *(ptr-2) == 'f') ? 1:2);		       i++)		    {		      for (j = 0; j < 8; j++)			{			  disk_no = (i * 0x80) + j;			  if ((disk_choice || disk_no == current_drive)			      && ! get_diskinfo (disk_no, &geom))			    {			      char dev_name[8];			      grub_sprintf (dev_name, "%cd%d", i ? 'h':'f', j);			      print_a_completion (dev_name);			    }			}		    }		}	      if (cdrom_drive != GRUB_INVALID_DRIVE		  && (disk_choice || cdrom_drive == current_drive)		  && (!ptr		      || *(ptr-1) == '('		      || (*(ptr-1) == 'd' && *(ptr-2) == 'c')))		print_a_completion ("cd");# ifdef SUPPORT_NETBOOT	      if (network_ready		  && (disk_choice || NETWORK_DRIVE == current_drive)		  && (!ptr		      || *(ptr-1) == '('		      || (*(ptr-1) == 'd' && *(ptr-2) == 'n')))		print_a_completion ("nd");# endif /* SUPPORT_NETBOOT */	      if (is_completion && *unique_string)		{		  ptr = buf;		  while (*ptr != '(')		    ptr--;		  ptr++;		  grub_strcpy (ptr, unique_string);		  if (unique == 1)		    {		      ptr += grub_strlen (ptr);		      if (*unique_string == 'h')			{			  *ptr++ = ',';			  *ptr = 0;			}		      else			{			  *ptr++ = ')';			  *ptr = 0;			}		    }		}	      if (! is_completion)		grub_putchar ('\n');	    }	  else	    {	      /* partition completions */	      if (part_choice == PART_CHOSEN		  && open_partition ()		  && ! IS_PC_SLICE_TYPE_BSD (current_slice))		{		  unique = 1;		  ptr = buf + grub_strlen (buf);		  if (*(ptr - 1) != ')')		    {		      *ptr++ = ')';		      *ptr = 0;		    }		}	      else		{		  if (! is_completion)		    grub_printf (" Possible partitions are:\n");		  real_open_partition (1);		  		  if (is_completion && *unique_string)		    {		      ptr = buf;		      while (*ptr++ != ',')			;		      grub_strcpy (ptr, unique_string);		    }		}	    }	}      else if (ptr && *ptr == '/')	{	  /* filename completions */	  if (! is_completion)	    grub_printf (" Possible files are:");	  	  dir (buf);	  	  if (is_completion && *unique_string)	    {	      ptr += grub_strlen (ptr);	      while (*ptr != '/')		ptr--;	      ptr++;	      	      grub_strcpy (ptr, unique_string);	      	      if (unique == 1)		{		  ptr += grub_strlen (unique_string);		  /* Check if the file UNIQUE_STRING is a directory.  */		  *ptr = '/';		  *(ptr + 1) = 0;		  		  dir (buf);		  		  /* Restore the original unique value.  */		  unique = 1;		  		  if (errnum)		    {		      /* Regular file */		      errnum = 0;		      *ptr = ' ';		      *(ptr + 1) = 0;		    }		}	    }	  	  if (! is_completion)	    grub_putchar ('\n');	}      else	errnum = ERR_BAD_FILENAME;    }  print_error ();  do_completion = 0;  if (errnum)    return -1;  else    return unique - 1;}#endif /* STAGE1_5 *//* *  This is the generic file open function. */intgrub_open (char *filename){#ifndef NO_DECOMPRESSION  compressed_file = 0;#endif /* NO_DECOMPRESSION */  /* if any "dir" function uses/sets filepos, it must     set it to zero before returning if opening a file! */  filepos = 0;  if (!(filename = setup_part (filename)))    return 0;#ifndef NO_BLOCK_FILES  block_file = 0;#endif /* NO_BLOCK_FILES */  /* This accounts for partial filesystem implementations. */  fsmax = MAXINT;  if (*filename != '/')    {#ifndef NO_BLOCK_FILES      char *ptr = filename;      int tmp, list_addr = BLK_BLKLIST_START;      filemax = 0;      while (list_addr < BLK_MAX_ADDR)	{	  tmp = 0;	  safe_parse_maxint (&ptr, &tmp);	  errnum = 0;	  if (*ptr != '+')	    {	      if ((*ptr && *ptr != '/' && !isspace (*ptr))		  || tmp == 0 || tmp > filemax)		errnum = ERR_BAD_FILENAME;	      else		filemax = tmp;	      break;	    }	  /* since we use the same filesystem buffer, mark it to	     be remounted */	  fsys_type = NUM_FSYS;	  BLK_BLKSTART (list_addr) = tmp;	  ptr++;	  if (!safe_parse_maxint (&ptr, &tmp)	      || tmp == 0	      || (*ptr && *ptr != ',' && *ptr != '/' && !isspace (*ptr)))	    {	      errnum = ERR_BAD_FILENAME;	      break;	    }	  BLK_BLKLENGTH (list_addr) = tmp;	  filemax += (tmp * SECTOR_SIZE);	  list_addr += BLK_BLKLIST_INC_VAL;	  if (*ptr != ',')	    break;	  ptr++;	}      if (list_addr < BLK_MAX_ADDR && ptr != filename && !errnum)	{	  block_file = 1;	  BLK_CUR_FILEPOS = 0;	  BLK_CUR_BLKLIST = BLK_BLKLIST_START;	  BLK_CUR_BLKNUM = 0;#ifndef NO_DECOMPRESSION	  return gunzip_test_header ();#else /* NO_DECOMPRESSION */	  return 1;#endif /* NO_DECOMPRESSION */	}#else /* NO_BLOCK_FILES */      errnum = ERR_BAD_FILENAME;#endif /* NO_BLOCK_FILES */    }  if (!errnum && fsys_type == NUM_FSYS)    errnum = ERR_FSYS_MOUNT;# ifndef STAGE1_5  /* set "dir" function to open a file */  print_possibilities = 0;# endif  if (!errnum && (*(fsys_table[fsys_type].dir_func)) (filename))    {#ifndef NO_DECOMPRESSION      return gunzip_test_header ();#else /* NO_DECOMPRESSION */      return 1;#endif /* NO_DECOMPRESSION */    }  return 0;}intgrub_read (char *buf, int len){  /* Make sure "filepos" is a sane value */  if ((filepos < 0) || (filepos > filemax))    filepos = filemax;  /* Make sure "len" is a sane value */  if ((len < 0) || (len > (filemax - filepos)))    len = filemax - filepos;  /* if target file position is past the end of     the supported/configured filesize, then     there is an error */  if (filepos + len > fsmax)    {      errnum = ERR_FILELENGTH;      return 0;    }#ifndef NO_DECOMPRESSION  if (compressed_file)    return gunzip_read (buf, len);#endif /* NO_DECOMPRESSION */#ifndef NO_BLOCK_FILES  if (block_file)    {      int size, off, ret = 0;      while (len && !errnum)	{	  /* we may need to look for the right block in the list(s) */	  if (filepos < BLK_CUR_FILEPOS)	    {	      BLK_CUR_FILEPOS = 0;	      BLK_CUR_BLKLIST = BLK_BLKLIST_START;	      BLK_CUR_BLKNUM = 0;	    }	  /* run BLK_CUR_FILEPOS up to filepos */	  while (filepos > BLK_CUR_FILEPOS)	    {	      if ((filepos - (BLK_CUR_FILEPOS & ~(SECTOR_SIZE - 1)))		  >= SECTOR_SIZE)		{		  BLK_CUR_FILEPOS += SECTOR_SIZE;		  BLK_CUR_BLKNUM++;		  if (BLK_CUR_BLKNUM >= BLK_BLKLENGTH (BLK_CUR_BLKLIST))		    {		      BLK_CUR_BLKLIST += BLK_BLKLIST_INC_VAL;		      BLK_CUR_BLKNUM = 0;		    }		}	      else		BLK_CUR_FILEPOS = filepos;	    }	  off = filepos & (SECTOR_SIZE - 1);	  size = ((BLK_BLKLENGTH (BLK_CUR_BLKLIST) - BLK_CUR_BLKNUM)		  * SECTOR_SIZE) - off;	  if (size > len)	    size = len;	  disk_read_func = disk_read_hook;	  /* read current block and put it in the right place in memory */	  devread (BLK_BLKSTART (BLK_CUR_BLKLIST) + BLK_CUR_BLKNUM,		   off, size, buf);	  disk_read_func = NULL;	  len -= size;	  filepos += size;	  ret += size;	  buf += size;	}      if (errnum)	ret = 0;      return ret;    }#endif /* NO_BLOCK_FILES */  if (fsys_type == NUM_FSYS)    {      errnum = ERR_FSYS_MOUNT;      return 0;    }  return (*(fsys_table[fsys_type].read_func)) (buf, len);}#ifndef STAGE1_5/* Reposition a file offset.  */intgrub_seek (int offset){  if (offset > filemax || offset < 0)    return -1;  filepos = offset;  return offset;}intdir (char *dirname){#ifndef NO_DECOMPRESSION  compressed_file = 0;#endif /* NO_DECOMPRESSION */  if (!(dirname = setup_part (dirname)))    return 0;  if (*dirname != '/')    errnum = ERR_BAD_FILENAME;  if (fsys_type == NUM_FSYS)    errnum = ERR_FSYS_MOUNT;  if (errnum)    return 0;  /* set "dir" function to list completions */  print_possibilities = 1;  return (*(fsys_table[fsys_type].dir_func)) (dirname);}#endif /* STAGE1_5 */void grub_close (void){#ifndef NO_BLOCK_FILES  if (block_file)    return;#endif /* NO_BLOCK_FILES */    if (fsys_table[fsys_type].close_func != 0)    (*(fsys_table[fsys_type].close_func)) ();}

⌨️ 快捷键说明

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