blocklist.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  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. struct wrapper_hook_data
  29. {
  30. void (*callback) (grub_disk_addr_t sector,
  31. unsigned int offset,
  32. unsigned int length,
  33. void *data);
  34. void *callback_data;
  35. };
  36. static grub_err_t
  37. callback_wrapper (grub_disk_addr_t sector,
  38. unsigned int offset, unsigned int length,
  39. char *buf, void *data)
  40. {
  41. struct wrapper_hook_data *wrap = data;
  42. wrap->callback (sector, offset, length, wrap->callback_data);
  43. return GRUB_ERR_NONE;
  44. }
  45. void
  46. grub_install_get_blocklist (grub_device_t root_dev,
  47. const char *core_path, const char *core_img,
  48. size_t core_size,
  49. void (*callback) (grub_disk_addr_t sector,
  50. unsigned offset,
  51. unsigned length,
  52. void *data),
  53. void *hook_data)
  54. {
  55. int i;
  56. char *tmp_img;
  57. char *core_path_dev;
  58. struct wrapper_hook_data wrap_hook_data = {
  59. .callback = callback,
  60. .callback_data = hook_data
  61. };
  62. core_path_dev = grub_make_system_path_relative_to_its_root (core_path);
  63. /* Make sure that GRUB reads the identical image as the OS. */
  64. tmp_img = xmalloc (core_size);
  65. for (i = 0; i < MAX_TRIES; i++)
  66. {
  67. grub_file_t file;
  68. grub_util_info ((i == 0) ? _("attempting to read the core image `%s' from GRUB")
  69. : _("attempting to read the core image `%s' from GRUB again"),
  70. core_path_dev);
  71. grub_disk_cache_invalidate_all ();
  72. file = grub_file_open (core_path_dev, GRUB_FILE_TYPE_NONE | GRUB_FILE_TYPE_NO_DECOMPRESS);
  73. if (file)
  74. {
  75. if (grub_file_size (file) != core_size)
  76. grub_util_info ("succeeded in opening the core image but the size is different (%d != %d)",
  77. (int) grub_file_size (file), (int) core_size);
  78. else if (grub_file_read (file, tmp_img, core_size)
  79. != (grub_ssize_t) core_size)
  80. grub_util_info ("succeeded in opening the core image but cannot read %d bytes",
  81. (int) core_size);
  82. else if (memcmp (core_img, tmp_img, core_size) != 0)
  83. {
  84. #if 0
  85. FILE *dump;
  86. FILE *dump2;
  87. dump = fopen ("dump.img", "wb");
  88. if (dump)
  89. {
  90. fwrite (tmp_img, 1, core_size, dump);
  91. fclose (dump);
  92. }
  93. dump2 = fopen ("dump2.img", "wb");
  94. if (dump2)
  95. {
  96. fwrite (core_img, 1, core_size, dump2);
  97. fclose (dump2);
  98. }
  99. #endif
  100. grub_util_info ("succeeded in opening the core image but the data is different");
  101. }
  102. else
  103. {
  104. grub_file_close (file);
  105. break;
  106. }
  107. grub_file_close (file);
  108. }
  109. else
  110. grub_util_info ("couldn't open the core image");
  111. if (grub_errno)
  112. grub_util_info ("error message = %s", grub_errmsg);
  113. grub_errno = GRUB_ERR_NONE;
  114. grub_util_biosdisk_flush (root_dev->disk);
  115. sleep (1);
  116. }
  117. if (i == MAX_TRIES)
  118. grub_util_error (_("cannot read `%s' correctly"), core_path_dev);
  119. grub_file_t file;
  120. /* Now read the core image to determine where the sectors are. */
  121. file = grub_file_open (core_path_dev, GRUB_FILE_TYPE_NONE | GRUB_FILE_TYPE_NO_DECOMPRESS);
  122. if (! file)
  123. grub_util_error ("%s", grub_errmsg);
  124. file->read_hook = callback_wrapper;
  125. file->read_hook_data = &wrap_hook_data;
  126. if (grub_file_read (file, tmp_img, core_size) != (grub_ssize_t) core_size)
  127. grub_util_error ("%s", _("failed to read the sectors of the core image"));
  128. grub_file_close (file);
  129. free (tmp_img);
  130. free (core_path_dev);
  131. }