OK, ich habe dieses Problem selbst gelöst, aber es war unangemessen schwierig.
Der Pfad zum übergeordneten Element ist in der .vhd-Datei in verschiedenen Formaten fest codiert. in meinem Fall sowohl relative als auch absolute Pfade, sowohl in ASCII als auch in UTF-16, für 4 Gesamtpfade.
Sie können die .vhd-Dateiformatspezifikation abrufen von Microsoft .
Aber ein schneller Scan mit Streicher oder ein ähnliches Dienstprogramm (ich verwende hier Cygwin), das nach Zeichenfolgendaten sucht, kann diese Offsets leichter finden als das Durchlaufen der VHD-Strukturen:
$ 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
Diese Zeichenfolgen werden mit viel Null-Byte-Abstand gespeichert. Ich habe einen Hex-Editor verwendet, um die Pfade zu neuen Orten zu aktualisieren.
Aber es hat nicht funktioniert; Die Pfade wurden im Virtual PC-Einstellungseditor abgeschnitten angezeigt. Die Zeichenfolgenlängen werden an anderer Stelle codiert. in meinem Fall bei 0x4AB, 0x4C3 usw. (Ich habe eine Hex-Suche nach den alten Pfadlängen durchgeführt). Ich habe diese Längen aktualisiert, aber dann wurde der VHD vom Virtual PC-Einstellungseditor als ungültig eingestuft. Ich stellte mir vor, dass jetzt eine Prüfsumme vorhanden war, lud die VHD-Spezifikation herunter, installierte den Word-Dokument-Viewer, damit ich die DOC-Datei lesen konnte, und schrieb dann das folgende Programm. Seine Ausgabe ist, wenn der Pfad zum virtuellen Datenträger übergeben wird, die aktualisierte Prüfsumme und der Speicherort für die Prüfsumme. Beispielausgabe:
opening Windows XP Mode-X.vhd
dynamic header seems to be at 0x200
new checksum: ffffda30 at 0x224
Durch die Eingabe dieser neuen Prüfsumme mit einem Hex-Editor funktionierte der vhd und der alte XP-Modus wurde erfolgreich gestartet.
Prüfsummenberechnungsprogramm:
#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;
}
Das hat mich ein paar Stunden gekostet, aber am Ende bin ich durchgekommen. Ich bin mir sicher, dass irgendwann jemand einen VHD-Editor veröffentlichen wird, der dies einfacher macht, aber zumindest bin ich wieder zu meinem alten XP-Modus übergegangen.
Aktualisieren: Es gibt eine viel einfachere Möglichkeit, mit PowerShell einige COM-Objekte zu skripten: https://obligatorymoniker.wordpress.com/2010/08/21/how-to-rebase-differencing-disk-vhds-or-how-to-change-the-parent-of-a-differencing-vhd-when- der-elternteil-ist umgezogen /
Im Wesentlichen:
$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