Как установить путь разностного родительского жесткого диска Virtual PC

3

У меня есть старый Windows XP Mode VHD, сохраненный из моей предыдущей системы, но я испытываю трудности с его запуском на новой системе.

VHD - это разностный диск, а его родительский элемент - стандартная база режима Windows XP; У меня все еще есть старый родитель, и я убедился, что он является двоичным идентичным базе XP Mode в моей новой установке XP Mode.

Но в новой системе путь к родительскому элементу разностного диска отличается от старого.

Когда я открываю настройки для .vmcx для моего старого режима XP и выбираю «Жесткий диск 1», «Файл виртуального жесткого диска» устанавливается правильно, но поле «Родительский диск:» указывает на неверный путь, и я не вижу способа отредактировать его.

Кто-нибудь знает как?

Барри Келли
источник

Ответы:

2

Хорошо, я решил эту проблему сам, но это было неоправданно сложно.

Путь к родителю жестко закодирован внутри .vhd в нескольких различных форматах; в моем случае как относительные, так и абсолютные пути, как в ASCII, так и в UTF-16, для 4 полных путей. Вы можете получить спецификацию формата файла .vhd от Microsoft .

Но быстрое сканирование со строками или аналогичная утилита (я использую Cygwin здесь), которая ищет строковые данные, может найти эти смещения легче, чем обход структур VHD:

$ strings -t x Windows\ XP\ Mode-X.vhd | head -200 | grep vhd
40000 ..\..\..\..\..\..\..\other\xp-mode\Windows XP Mode base.vhd
40200 C:\other\xp-mode\Windows XP Mode base.vhd
$ strings -t x -e l Windows\ XP\ Mode-X.vhd | head -200 | grep vhd
40400 ..\..\..\..\..\..\..\other\xp-mode\Windows XP Mode base.vhd
40600 C:\other\xp-mode\Windows XP Mode base.vhd

Эти строки хранятся с большим количеством пустых байтов; Я использовал шестнадцатеричный редактор, чтобы обновить пути к новым местам.

Но это не сработало; пути были показаны усеченными в редакторе настроек Virtual PC. Длина строки кодируется в другом месте; в моем случае 0x4AB, 0x4C3 и т. д. (я выполнил шестнадцатеричный поиск старых путей). Я обновил эти длины, но тогда редактор VHD считал недействительным VHD. Я решил, что теперь включена контрольная сумма, скачал спецификацию VHD, установил средство просмотра документов Word, чтобы я мог прочитать .doc, и затем я написал программу ниже. Его вывод, когда передается путь к VHD, является обновленной контрольной суммой и местоположением контрольной суммы; пример вывода:

opening Windows XP Mode-X.vhd
dynamic header seems to be at 0x200
new checksum: ffffda30 at 0x224

Ввод этой новой контрольной суммы с помощью шестнадцатеричного редактора заставил VHD работать, и старый режим XP успешно загрузился.

Программа расчета контрольной суммы:

#include <fcntl.h>
#include <stdio.h>
#include <io.h>
#include <stdlib.h>
#include <unistd.h>

const int checksum_offset = 36;

long long flip_endian_ll(long long x)
{
    return ((x & 0x00000000000000FFULL) << 56)
        |  ((x & 0x000000000000FF00ULL) << 40)
        |  ((x & 0x0000000000FF0000ULL) << 24)
        |  ((x & 0x00000000FF000000ULL) << 8)
        |  ((x & 0x000000FF00000000ULL) >> 8)
        |  ((x & 0x0000FF0000000000ULL) >> 24)
        |  ((x & 0x00FF000000000000ULL) >> 40)
        |  ((x & 0xFF00000000000000ULL) >> 56);
}

int die(const char *msg)
{
    fprintf(stderr, "error: %s\n", msg);
    exit(1);
}

int main(int argc, const char *const *args)
{
    int f, r;
    long long dyn_ofs;
    unsigned char dyn_header[1024];

    if (argc != 2)
    {
        fprintf(stderr, "expected: .vhd argument\n");
        return 1;
    }

    printf("opening %s\n", args[1]);
    f = open(args[1], O_RDONLY | O_BINARY);
    if (f < 0)
        die("failed open");
    r = lseek(f, 0x10, SEEK_SET);
    if (r < 0)
        die("seek failed");
    r = read(f, &dyn_ofs, sizeof(dyn_ofs));
    if (r != 8)
        die("failed read");
    dyn_ofs = flip_endian_ll(dyn_ofs);
    printf("dynamic header seems to be at 0x%llx\n", dyn_ofs);

    r = lseek(f, dyn_ofs, SEEK_SET);
    if (r < 0)
        die("seek failed");
    r = read(f, dyn_header, sizeof(dyn_header));
    if (r != sizeof(dyn_header))
        die("read of dynamic header failed");

    if (memcmp("cxsparse", dyn_header, 8) != 0)
        die("dynamic header didn't start with cxsparse");

    {
        unsigned long sum = 0;
        int i;

        for (i = checksum_offset; i < checksum_offset + 4; ++i)
            dyn_header[i] = 0;
        for (i = 0; i < sizeof(dyn_header); ++i)
            sum += dyn_header[i];
        sum = ~sum; // flip_endian_l(~sum);
        printf("new checksum: %.8x at 0x%llx\n", sum, dyn_ofs + checksum_offset);
    }
    return 0;
}

Это стоило мне нескольких часов, но в итоге я справился. Я уверен, что кто-то в конце концов опубликует редактор VHD, который сделает это проще, но, по крайней мере, я снова перешел в свой старый режим XP.

Обновление: есть гораздо более простой способ сделать это, используя PowerShell для создания сценариев некоторых COM-объектов: https://obligatorymoniker.wordpress.com/2010/08/21/how-to-rebase-differencing-disk-vhds-or-how -в-изменение-The-родитель-о-а-разностного-VHD-когда-The-родитель-имеет-переместил /

По сути:

$vpc=new-object -com VirtualPC.Application
$VHDChild = $vpc.GetHardDisk("C:\NAV2010.06.10_Diff")
$VHDParent = $vpc.GetHardDisk("\\devnas\Data_Backups SQLCluster1\NAV2010.06.10.vhd")
$VHDChild.Parent = $VHDParent
Барри Келли
источник
1
Я почти уверен, что сдался бы, прежде чем модифицировать файлы VHD с помощью шестнадцатеричного редактора несколько раз, прочитав спецификацию VHD, а затем написав приложение c ++ (?) Для вычисления контрольных сумм VHD. Если бы я не придумал «легкий» способ сделать это, я бы не пошел так далеко. Вы, сэр, вдохновили меня продвинуться дальше, чем я делал в прошлом, +1.
Крис Магнусон
2

В качестве альтернативы, если вы не хотите писать код на C ++ для манипулирования файлом .VHD:

... из Virtual PC, выберите «Virtual Disk Wizard», «Edit существующий виртуальный диск» и выберите неисправный разностный диск, вы получите следующее сообщение:

«Родительский виртуальный жесткий диск был удален или был перемещен из своего предыдущего местоположения. Пожалуйста, выберите новое местоположение родительского виртуального жесткого диска».

Нажмите [Изменить ...] и найдите родительский диск.

Оли Б
источник