blocklist.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. /* grub-setup.c - make GRUB usable */
  2. /*
  3. * GRUB -- GRand Unified Bootloader
  4. * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011 Free Software Foundation, Inc.
  5. *
  6. * GRUB is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * GRUB is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include <config.h>
  20. #include <grub/disk.h>
  21. #include <grub/file.h>
  22. #include <grub/partition.h>
  23. #include <grub/util/misc.h>
  24. #include <grub/util/install.h>
  25. #include <grub/emu/hostdisk.h>
  26. #include <string.h>
  27. #define MAX_TRIES 5
  28. void
  29. grub_install_get_blocklist (grub_device_t root_dev,
  30. const char *core_path, const char *core_img,
  31. size_t core_size,
  32. void (*callback) (grub_disk_addr_t sector,
  33. unsigned offset,
  34. unsigned length,
  35. void *data),
  36. void *hook_data)
  37. {
  38. int i;
  39. char *tmp_img;
  40. char *core_path_dev;
  41. core_path_dev = grub_make_system_path_relative_to_its_root (core_path);
  42. /* Make sure that GRUB reads the identical image as the OS. */
  43. tmp_img = xmalloc (core_size);
  44. for (i = 0; i < MAX_TRIES; i++)
  45. {
  46. grub_file_t file;
  47. grub_util_info ((i == 0) ? _("attempting to read the core image `%s' from GRUB")
  48. : _("attempting to read the core image `%s' from GRUB again"),
  49. core_path_dev);
  50. grub_disk_cache_invalidate_all ();
  51. file = grub_file_open (core_path_dev, GRUB_FILE_TYPE_NONE | FILE_TYPE_NO_DECOMPRESS);
  52. if (file)
  53. {
  54. if (grub_file_size (file) != core_size)
  55. grub_util_info ("succeeded in opening the core image but the size is different (%d != %d)",
  56. (int) grub_file_size (file), (int) core_size);
  57. else if (grub_file_read (file, tmp_img, core_size)
  58. != (grub_ssize_t) core_size)
  59. grub_util_info ("succeeded in opening the core image but cannot read %d bytes",
  60. (int) core_size);
  61. else if (memcmp (core_img, tmp_img, core_size) != 0)
  62. {
  63. #if 0
  64. FILE *dump;
  65. FILE *dump2;
  66. dump = fopen ("dump.img", "wb");
  67. if (dump)
  68. {
  69. fwrite (tmp_img, 1, core_size, dump);
  70. fclose (dump);
  71. }
  72. dump2 = fopen ("dump2.img", "wb");
  73. if (dump2)
  74. {
  75. fwrite (core_img, 1, core_size, dump2);
  76. fclose (dump2);
  77. }
  78. #endif
  79. grub_util_info ("succeeded in opening the core image but the data is different");
  80. }
  81. else
  82. {
  83. grub_file_close (file);
  84. break;
  85. }
  86. grub_file_close (file);
  87. }
  88. else
  89. grub_util_info ("couldn't open the core image");
  90. if (grub_errno)
  91. grub_util_info ("error message = %s", grub_errmsg);
  92. grub_errno = GRUB_ERR_NONE;
  93. grub_util_biosdisk_flush (root_dev->disk);
  94. sleep (1);
  95. }
  96. if (i == MAX_TRIES)
  97. grub_util_error (_("cannot read `%s' correctly"), core_path_dev);
  98. grub_file_t file;
  99. /* Now read the core image to determine where the sectors are. */
  100. file = grub_file_open (core_path_dev, GRUB_FILE_TYPE_NONE | FILE_TYPE_NO_DECOMPRESS);
  101. if (! file)
  102. grub_util_error ("%s", grub_errmsg);
  103. file->read_hook = callback;
  104. file->read_hook_data = hook_data;
  105. if (grub_file_read (file, tmp_img, core_size) != (grub_ssize_t) core_size)
  106. grub_util_error ("%s", _("failed to read the sectors of the core image"));
  107. grub_file_close (file);
  108. free (tmp_img);
  109. free (core_path_dev);
  110. }