Немного о Windows

Опубликовано 24 Сентября, 2008 под тегами Windows, Cheats, Windows

Это, конечно, злостный оффтопик, но я не могу не изложить свои изыскания на тему присвоения букв дискам. Информация, по меньшей мере, любопытная. Дальше речь пойдет преимущественно о Windows XP, но нет никаких принципиальных отличий ни от каких NT 5.

Итак, как обычно, изложу мысль в форме HowTo. ~Вся\ информация\ для\ “продвинутого\ пользователя”\ написана\ мелким\ шрифтом,\ если\ хочется\ выяснить,\ в\ чем\ же\ суть,\ не\ читая,\ то\ милости\ прошу~ Допустим, имеется (не столь фантастическая) ситуация, когда нужно “передвинуть” основной раздел Windows (то есть изменить стартовый сектор раздела). В принципе, с этим отлично справляется GParted, и все бы было хорошо, если бы при этом не терялась привязка раздела к “букве диска”. Проще говоря, если передвинуть основной раздел C: вперед, то никто не обещает, что он вдруг не превратится в раздел D:. Подобная “потеря привязки” черевата потерей системы, поскольку Windows, естественно, не загрузится, если изменится буква системного раздела. Характерный признак такой ситуации - при загрузке XP вместо экрана приветствия “вечно” висит логотип. Причины такого поведения станут ясны ниже. Простейший способ избежать таких сложностей - не перемещать системный раздел. Но мы ведь не ищем легких путей :)

Итак, нам нужно:

  1. Возможность загрузиться в Linux (Live CD/USB/DVD, Multiboot, etc)
  2. GNU fdisk
  3. chntpw
  4. Умение считать
  5. Желание возиться

Надеюсь, с перемещением раздела не возникнет никаких сложностей. Чтобы GParted мог переместить раздел NTFS, нужен пакет ntfsutils. В принципе, в нем есть консольная утилита resizentfs, оболочкой для которой, по сути, и служит в данном случае GParted, но в общем использование ее напрямую довольно бессмысленно. Дальше, придется поиграться с системным реестром, причем не самым удобным способом. Монтируем основной раздел Windows (допустим, /dev/sda2)

mount -t ntfs-3g /dev/sda2 /mnt/xp

Запускаем chntpw в режиме редактирования реестра (ясно, что его сначала стоит поставить - в репозитариях Debian и Ubuntu он есть):

chntpw -e /mnt/xp/WINDOWS/system32/config/system

WINDOWS/system32/config/system - это путь к файлу, содержащему ветку HKEY_LOCAL_MACHINE Дальше переходим в ключ MountedDevices:

cd MountedDevices

И смотрим на список значений:

ls

~В\ этом\ ключе,\ как\ следует\ из\ MSDN,\ Windows\ хранит\ привязки\ к\ названиям\ устройств.\ Название\ значения\ -\ это\ название\ устройства,\ содержимое\ -\ уникальный\ идентификатор\ раздела.\ О\ том,\ как\ генерируются\ уникальные\ идентификаторы\ разделов,\ ниже~ В случае жестких дисков, нас интересуют значения типа REG_BINARY и длиной 12 байт. Смотрим на значение с именем \DosDevices\, например, \DosDevices\C:

cat \\DosDevices\\C:

Теперь самая нудная задача: нужно найти среди значений с именами \??\Volume{…} такой, содержимое которого соответствует содержимому \DosDevices\C: Тем же cat это делается. Предположим, что такое значение уже найдено, скажем, \??\Volume{31294124-35f4-11dd-87a2-001e8c269c8d} Теперь нужно составить новый идентификатор раздела и записать его в эти значения. ~Идентификатор\ раздела\ состоит\ из\ конкатенации\ идентификатора\ диска\ (DiskID,\ иногда\ известный\ как\ серийный\ номер\ NT)\ и\ стартового\ байта\ раздела.\ DiskID\ -\ первые\ 4\ байта\ идентификатора\ (в\ нотации\ Little\ Endian,\ то\ есть\ старший\ байт\ -\ последний),\ номер\ первого\ байта\ раздела\ -\ все\ остальное\ (так\ же\ в\ нотации\ Little\ Endian).~ Поскольку речь идет о перемещении одного раздела в пределах диска, нужно исправить только последние 8 байт. В соседнем шелле узнаем стартовый сектор раздела:

fdisk -l -u /dev/sda
Диск /dev/sda: 80.0 ГБ, 80026361856 байт
255 heads, 63 sectors/track, 9729 cylinders, всего 156301488 секторов
Units = секторы of 1 * 512 = 512 bytes
Disk identifier: 0x000e90fe <--- DiskID

Устр-во Загр     Начало       Конец       Блоки   Id  Система
/dev/sda1              63     4209029     2104483+  83  Linux
/dev/sda2   *     4209030   156280319    76035645    7  HPFS/NTFS

~Для\ интересующихся,\ я\ указал\ место,\ где\ написан\ DiskID~ Начало /dev/sda2 при таком выводе - 4209030 сектор. Размер сектора - 512 байт, поэтому полученное число нужно умножить на 512 и перевести в Hex:

printf '%x\n' `echo $((4209030*512))`
80730c00

Полученное число нужно парами с конца записать в соответствующие значения реестра. Возващаемся в шелл, в котором запущен chntpw и выполняем:

ed \\DosDevices\\C:

:4 00 0c 73 80 00 00 00 00
s 

~:4\ означает\ “записать\ после\ 4\ байта\ последовательность”~ И такую же последовательность для \??\Volume{…}, найденного ранее. Обратите внимание на четыре пары нулей в конце, это важно. Общее количество байт должно быть равно 8, иначе могут остаться “хвосты” от прошлой записи. после этого выходим, выполняя q, на вопрос отвечаем утвердительно. Собственно, все.