5

I want to calculate the end offset of a parent locator in a VHD. Here is a part of the VHD header:

Cookie: cxsparse
Data offset: 0xffffffffffffffff
Table offset: 0x2000
Header version: 0x00010000
Max table entries: 10240
Block size: 0x200000
Checksum: 4294956454
Parent Unique Id: 0x9678bf077e719640b55e40826ce5d178
Parent time stamp: 525527478
Reserved: 0
Parent Unicode name:
Parent locator 1:
- platform code: 0x57326b75
- platform_data_space: 4096
- platform_data_length: 86
- reserved: 0
- platform_data_offset: 0x1000
Parent locator 2:
- platform code: 0x57327275
- platform_data_space: 65536
- platform_data_length: 34
- reserved: 0
- platform_data_offset: 0xc000

Some definitions from the Virtual Hard Disk Image Format Specification:

"Table Offset: This field stores the absolute byte offset of the Block Allocation Table (BAT) in the file. Platform Data Space: This field stores the number of 512-byte sectors needed to store the parent hard disk locator. Platform Data Offset: This field stores the absolute file offset in bytes where the platform specific file locator data is stored. Platform Data Length. This field stores the actual length of the parent hard disk locator in bytes."

Based on this the end offset of the two parent locators should be: data offset + 512 * data space:

0x1000 + 512 * 4096 = 0x201000
0xc000 + 512 * 65536 = 0x200c000

But if one uses only data offset + data space:

0x1000 + 4096 = 0x2000 //end of parent locator 1, begin of BAT
0xc000 + 65536 = 0x1c000

This latter calculation makes much more sense: the end of the first parent locator is the beginning of the BAT (see header data above); and since the first BAT entry is 0xe7 (sector offset), this corresponds to file offset 0x1ce00 (sector offset * 512), which is OK, if the second parent locator ends at 0x1c000.

But if one uses the formula data offset + 512 * data space, he ends up having other data written in the parent locator. (But, in this example there would be no data corruption, since Platform Data Length is very small)

So is this a mistake in the specification, and the sentence

"Platform Data Space: This field stores the number of 512-byte sectors needed to store the parent hard disk locator."

should be

"Platform Data Space: This field stores the number of bytes needed to store the parent hard disk locator."?

robert
  • 3,539
  • 3
  • 35
  • 56
  • My first guess would be that whatever is displaying the VHD header for you has already multiplied Platform Data Length by 512. You'd need to look at the actual binary contents of the header to be sure. – Harry Johnston Nov 23 '16 at 21:52
  • To extract header information I used my own tool, but I do not multiply anything. Here is the raw data from a hex editor: `57 32 6B 75 00 00 10 00 00 00 00 54 00 00 00 00 00 00 00 00 00 00 10 00 57 32 72 75 00 01 00 00`. After platform code 0x57326b75 (W2ku) follows 0x1000 (4096) and after 0x57327275 (W2ru) follows 0x10000 (65536). – robert Nov 24 '16 at 07:56
  • Certainly looks like it is a byte count and not a sector count. That might be a mistake in the specifications, or it might be a mistake on the part of whatever software generated the VHD in question; either way it would probably go unnoticed provided the originally reserved space was always adequate. – Harry Johnston Nov 24 '16 at 08:35
  • Is there a MS tool that changes the contents of the parent hard disk locator for an existing VHD? If so, it should refuse to do so if the data space isn't big enough for the new data, so perhaps you could use a binary editor to change the data space field for a VHD to 1 and see whether the tool interpreted that as "enough room for 512 bytes of data" or "enough room for 1 byte of data". :-) – Harry Johnston Nov 24 '16 at 08:42

1 Answers1

5

Apparently Microsoft does not care about correcting their mistake, this being already discovered by Virtualbox developers. VHD.cpp contains the following comment:

/*
 * The VHD spec states that the DataSpace field holds the number of sectors
 * required to store the parent locator path.
 * As it turned out VPC and Hyper-V store the amount of bytes reserved for the
 * path and not the number of sectors.
 */
robert
  • 3,539
  • 3
  • 35
  • 56