📄 disk_io.c
字号:
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) <= 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 j;// struct geometry tmp_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' && *(ptr-2) != 'm' && *(ptr-2) != 'r')) { int k; for (k = (ptr && (*(ptr-1) == 'd' && *(ptr-2) == 'h') ? 1:0); k < (ptr && (*(ptr-1) == 'd' && *(ptr-2) == 'f') ? 1:2); k++) {#define HARD_DRIVES (*((char *)0x475))#define FLOPPY_DRIVES ((*(char*)0x410 & 1)?(*(char*)0x410 >> 6) + 1 : 0)#ifdef GRUB_UTIL for (j = 0; j < 8; j++)#else for (j = 0; j < (k ? HARD_DRIVES : FLOPPY_DRIVES); j++)#endif#undef HARD_DRIVES#undef FLOPPY_DRIVES { i = (k * 0x80) + j; if ((disk_choice || i == current_drive) && ! get_diskinfo (i, &tmp_geom)) { char dev_name[8]; grub_sprintf (dev_name, "%cd%d", k ? 'h':'f', j); print_a_completion (dev_name); } } } } if (rd_base != 0xffffffff && (disk_choice || ram_drive == current_drive) && (!ptr || *(ptr-1) == '(' || (*(ptr-1) == 'd' && *(ptr-2) == 'r'))) print_a_completion ("rd"); 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");#ifndef GRUB_UTIL if (atapi_dev_count && (!ptr || *(ptr-1) == '(' || (*(ptr-1) == 'd' && *(ptr-2) == 'c'))) { for (j = 0; j < atapi_dev_count; j++) if (disk_choice || min_cdrom_id + j == current_drive) { char dev_name[8]; grub_sprintf (dev_name, "cd%d", j); print_a_completion (dev_name); } }#endif# 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 */# ifdef FSYS_PXE if (pxe_entry && (disk_choice || PXE_DRIVE == current_drive) && (!ptr || *(ptr-1) == '(' || (*(ptr-1) == 'd' && *(ptr-2) == 'p'))) print_a_completion ("pd");# endif /* FSYS_PXE */ 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 */#ifndef NO_BLOCK_FILESstatic int block_file = 0;#endif /* NO_BLOCK_FILES *//* * 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 != '/') {#ifdef NO_BLOCK_FILES return !(errnum = ERR_BAD_FILENAME);#else char *ptr = filename; unsigned long tmp, list_addr = FSYS_BUF + 12; /* BLK_BLKLIST_START */ filemax = 0; while (list_addr < FSYS_BUF + 0x77F9) /* BLK_MAX_ADDR */ { tmp = 0; safe_parse_maxint (&ptr, (int *)(void *)&tmp); errnum = 0; if (*ptr != '+') { /* Set FILEMAX in bytes, Undocumented!! */ /* The FILEMAX must not exceed the one calculated from * all the blocks in the list. */ if ((*ptr && *ptr != '/' && !isspace (*ptr)) || tmp == 0 || tmp > filemax) break; /* failure */ filemax = tmp; goto block_file; /* success */ } /* since we use the same filesystem buffer, mark it to be remounted */ fsys_type = NUM_FSYS; *((unsigned long*)list_addr) = tmp; /* BLK_BLKSTART */ ptr++; /* skip the plus sign */ safe_parse_maxint (&ptr, (int *)(void *)&tmp); if (errnum) return 0; if (!tmp || (*ptr && *ptr != ',' && *ptr != '/' && !isspace (*ptr))) break; /* failure */ *((unsigned long*)(list_addr+4)) = tmp; /* BLK_BLKLENGTH */ tmp *= buf_geom.sector_size; filemax += tmp; list_addr += 8; /* BLK_BLKLIST_INC_VAL */ if (*ptr != ',') goto block_file; /* success */ ptr++; /* skip the comma sign */ } /* while (list_addr < FSYS_BUF + 0x77F9) */ return !(errnum = ERR_BAD_FILENAME);// if (list_addr < FSYS_BUF + 0x77F9 && ptr != filename)// {block_file: block_file = 1; (*((unsigned long*)FSYS_BUF))= 0; /* BLK_CUR_FILEPOS */ (*((unsigned long*)(FSYS_BUF+4))) = FSYS_BUF + 12; /* let BLK_CUR_BLKLIST = BLK_BLKLIST_START */ (*((unsigned long*)(FSYS_BUF+8))) = 0; /* BLK_CUR_BLKNUM */ if (current_drive == ram_drive && filemax == 512 && filemax < rd_size && (*(long *)(FSYS_BUF + 12)) == 0) { filemax = rd_size; *(long *)(FSYS_BUF + 16) = (filemax + 0x1FF) >> 9; }#ifdef NO_DECOMPRESSION return 1;#else return gunzip_test_header ();#endif// }#endif /* block files */ } /* if (*filename != '/') */ 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 (relative_path) { if (grub_strlen(saved_dir) + grub_strlen(filename) >= sizeof(open_filename)) { errnum = ERR_WONT_FIT; return 0; } grub_sprintf (open_filename, "%s%s", saved_dir, filename); } if (!errnum && (*(fsys_table[fsys_type].dir_func)) (relative_path ? open_filename : filename)) {#ifdef NO_DECOMPRESSION return 1;#else return gunzip_test_header ();#endif } return 0;}unsigned longgrub_read (char *buf, unsigned long 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) { unsigned long size, off, ret = 0; while (len && !errnum) { /* we may need to look for the right block in the list(s) */ if (filepos < (*((unsigned long*)FSYS_BUF)) /* BLK_CUR_FILEPOS */) { (*((unsigned long*)FSYS_BUF)) = 0; (*((unsigned long*)(FSYS_BUF+4))) = FSYS_BUF + 12; /* let BLK_CUR_BLKLIST = BLK_BLKLIST_START */ (*((unsigned long*)(FSYS_BUF+8))) = 0; /* BLK_CUR_BLKNUM */ } /* run BLK_CUR_FILEPOS up to filepos */ while (filepos > (*((unsigned long*)FSYS_BUF))) { if ((filepos - ((*((unsigned long*)FSYS_BUF)) & ~(buf_geom.sector_size - 1))) >= buf_geom.sector_size) { (*((unsigned long*)FSYS_BUF)) += buf_geom.sector_size; (*((unsigned long*)(FSYS_BUF+8)))++; if ((*((unsigned long*)(FSYS_BUF+8))) >= *((unsigned long*) ((*((unsigned long*)(FSYS_BUF+4))) + 4)) ) { (*((unsigned long*)(FSYS_BUF+4))) += 8; /* BLK_CUR_BLKLIST */ (*((unsigned long*)(FSYS_BUF+8))) = 0; /* BLK_CUR_BLKNUM */ } } else (*((unsigned long*)FSYS_BUF)) = filepos; } off = filepos & (buf_geom.sector_size - 1); size = ((*((unsigned long*)((*((unsigned long*)(FSYS_BUF+4))) + 4)) - (*((unsigned long*)(FSYS_BUF+8)))) * buf_geom.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 ((*((unsigned long*)(*((unsigned long*)(FSYS_BUF+4))))) + (*((unsigned long*)(FSYS_BUF+8))), off, size, buf);//printf("devread ok\n"); 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);}voidgrub_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 + -