Я уронил свой ноутбук, пока Windows готовился к переходу в спящий режим, и в результате у меня сломалась голова на жестком диске. (Учит меня в следующий раз использовать жесткий диск и/или ноутбук с датчиком свободного падения.) В любом случае, запуск SpinRite для восстановления данных привел к тому, что все запасные сектора на диске были израсходованы для всех восстанавливаемых секторов на данный момент. SpinRite все еще работает прямо сейчас, но, поскольку запасных секторов больше не будет, я думаю, что это будет бесполезное занятие, кроме как сказать мне, где все поврежденные сектора.
Во всяком случае, я планирую написать приложение, чтобы попытаться спасти данные с жесткого диска. Из моих прошлых набегов на дефрагментацию я знаю, что могу использовать FSCTL_GET_RETRIEVAL_POINTERS для определения номеров логических кластеров для любого данного файла.
Как мне попытаться прочитать сектора для этого фактического кластера? Когда я копался в списке MSDN для кодов управления дисками, файлами и томами, у меня ничего не выскочило из того, как я получаю фактические данные кластера.
Стоит ли мне даже пытаться читать на таком низком уровне? Должен ли я вместо этого выполнять вызовы SetFilePointer() и ReadFile(), чтобы получить соответствующие смещения размера кластера в файле и прочитать фрагменты размера кластера?
Если файл, который я пытаюсь прочитать, имеет поврежденный сектор, пометит ли NTFS весь файл как поврежденный и запретит мне доступ к файлу в будущем? Если да, то как я могу сказать NTFS не помечать файл как плохой или мертвый? (Помните, что на жестком диске закончились свободные сектора для переназначения.)
Должен ли я стряхнуть пыль со своих знаний *nix и выяснить, как читать из /dev/ ?
Обновление: я нашел ответ на свой вопрос. :-) Решение заключается в выполнении SetFilePointer() и ReadFile() для дескриптора тома, а не для дескриптора файла.