123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157 |
- /* grub-setup.c - make GRUB usable */
- /*
- * GRUB -- GRand Unified Bootloader
- * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011 Free Software Foundation, Inc.
- *
- * GRUB is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * GRUB is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
- */
- #include <config.h>
- #include <grub/disk.h>
- #include <grub/file.h>
- #include <grub/partition.h>
- #include <grub/util/misc.h>
- #include <grub/util/install.h>
- #include <grub/emu/hostdisk.h>
- #include <string.h>
- #define MAX_TRIES 5
- struct wrapper_hook_data
- {
- void (*callback) (grub_disk_addr_t sector,
- unsigned int offset,
- unsigned int length,
- void *data);
- void *callback_data;
- };
- static grub_err_t
- callback_wrapper (grub_disk_addr_t sector,
- unsigned int offset, unsigned int length,
- char *buf, void *data)
- {
- struct wrapper_hook_data *wrap = data;
- wrap->callback (sector, offset, length, wrap->callback_data);
- return GRUB_ERR_NONE;
- }
- void
- grub_install_get_blocklist (grub_device_t root_dev,
- const char *core_path, const char *core_img,
- size_t core_size,
- void (*callback) (grub_disk_addr_t sector,
- unsigned offset,
- unsigned length,
- void *data),
- void *hook_data)
- {
- int i;
- char *tmp_img;
- char *core_path_dev;
- struct wrapper_hook_data wrap_hook_data = {
- .callback = callback,
- .callback_data = hook_data
- };
- core_path_dev = grub_make_system_path_relative_to_its_root (core_path);
- /* Make sure that GRUB reads the identical image as the OS. */
- tmp_img = xmalloc (core_size);
- for (i = 0; i < MAX_TRIES; i++)
- {
- grub_file_t file;
- grub_util_info ((i == 0) ? _("attempting to read the core image `%s' from GRUB")
- : _("attempting to read the core image `%s' from GRUB again"),
- core_path_dev);
- grub_disk_cache_invalidate_all ();
- file = grub_file_open (core_path_dev, GRUB_FILE_TYPE_NONE | GRUB_FILE_TYPE_NO_DECOMPRESS);
- if (file)
- {
- if (grub_file_size (file) != core_size)
- grub_util_info ("succeeded in opening the core image but the size is different (%d != %d)",
- (int) grub_file_size (file), (int) core_size);
- else if (grub_file_read (file, tmp_img, core_size)
- != (grub_ssize_t) core_size)
- grub_util_info ("succeeded in opening the core image but cannot read %d bytes",
- (int) core_size);
- else if (memcmp (core_img, tmp_img, core_size) != 0)
- {
- #if 0
- FILE *dump;
- FILE *dump2;
- dump = fopen ("dump.img", "wb");
- if (dump)
- {
- fwrite (tmp_img, 1, core_size, dump);
- fclose (dump);
- }
- dump2 = fopen ("dump2.img", "wb");
- if (dump2)
- {
- fwrite (core_img, 1, core_size, dump2);
- fclose (dump2);
- }
- #endif
- grub_util_info ("succeeded in opening the core image but the data is different");
- }
- else
- {
- grub_file_close (file);
- break;
- }
- grub_file_close (file);
- }
- else
- grub_util_info ("couldn't open the core image");
- if (grub_errno)
- grub_util_info ("error message = %s", grub_errmsg);
- grub_errno = GRUB_ERR_NONE;
- grub_util_biosdisk_flush (root_dev->disk);
- sleep (1);
- }
- if (i == MAX_TRIES)
- grub_util_error (_("cannot read `%s' correctly"), core_path_dev);
- grub_file_t file;
- /* Now read the core image to determine where the sectors are. */
- file = grub_file_open (core_path_dev, GRUB_FILE_TYPE_NONE | GRUB_FILE_TYPE_NO_DECOMPRESS);
- if (! file)
- grub_util_error ("%s", grub_errmsg);
- file->read_hook = callback_wrapper;
- file->read_hook_data = &wrap_hook_data;
- if (grub_file_read (file, tmp_img, core_size) != (grub_ssize_t) core_size)
- grub_util_error ("%s", _("failed to read the sectors of the core image"));
- grub_file_close (file);
- free (tmp_img);
- free (core_path_dev);
- }
|