A while ago I became very interested in virtualization and how Microsoft Virtual PC works. I quickly came up against VHD (Virtual Hard Disk) files and after learning a little about them I realised that you could use them to start learning 32-bit Assembly and build your own bootloader or operating system. All pretty obvious stuff but it all seemed so magical… so I looked for a good interface to let me edit VHD files and couldn’t really find anything that was as visual as I wanted which meant it was time to start coding.

After reading the specification for VHD files (which is here) I learned that there are three types of VHD file which are Fixed, Dynamic and Differencing. The most basic of these is the fixed disk type which is just one file with a block of data representing a hard disk surrounded by a header and a footer. The dynamic disk grows by block sizes as you add data to it but never goes beyond the maximum capacity. This is how you can have a virtualized 60Gb drive taking up only 4Gb – it is because the actual space used is only what is needed rather than the full allocation as is the case with fixed virtual disks. I won’t go into differencing disks in this post because I did nothing with them but they are used to represent the differences between an existing VHD and another state of that VHD. A differencing VHD file relies on having a parent which can be a fixed, dynamic or even another differencing disk.

Footer Format

All VHD disk types share a common footer format which is detailed in the VHD format specification document but here’s the brief version.

Hard Disk Footer Fields Size (bytes)
Cookie 8
Features 4
File Format Version 4
Data Offset 8
Time Stamp 4
Creator Application 4
Creator Version 4
Creator Host OS 4
Original Size 8
Current Size 8
Disk Geometry 4
Disk Type 4
Checksum 4
Unique Id 16
Saved State 1
Reserved 427

Using this table you could build an object to easily read and modify these values from the VHD files footer. Doing this would then allow you to manipulate fixed disks by changing their size (Current Size) or doing other funky things. To save the footer as a fully functional FIXED DISK VHD file you save out the data block as large as needed but in multiples of a ‘block’ size and end with the 512 byte footer as detailed above.

When any changes are made you must re-create the Checksum which can be done like so (this is an example from my code, don’t forget that your variables names are likely to be different).

public void UpdateChecksum()
   uint uChecksum = 0;
   byte[] tmp = new byte[512];
   this.Checksum = 0;
   Array.Copy(_cookie, 0, tmp, 0, _cookie.Length);
   Array.Copy(_features, 0, tmp, 8, _features.Length);
   Array.Copy(_fileFormatVersion, 0, tmp, 12, _fileFormatVersion.Length);
   Array.Copy(_dataOffset, 0, tmp, 16, _dataOffset.Length);
   Array.Copy(_timeStamp, 0, tmp, 24, _timeStamp.Length);
   Array.Copy(_createApp, 0, tmp, 28, _createApp.Length);
   Array.Copy(_creatorVersion, 0, tmp, 32, _creatorVersion.Length);
   Array.Copy(_creatorHostOS, 0, tmp, 36, _creatorHostOS.Length);
   Array.Copy(_originalSize, 0, tmp, 40, _originalSize.Length);
   Array.Copy(_currentSize, 0, tmp, 48, _currentSize.Length);
   Array.Copy(_diskGeometry, 0, tmp, 56, _diskGeometry.Length);
   Array.Copy(_diskType, 0, tmp, 60, _diskType.Length);
   Array.Copy(_checksum, 0, tmp, 64, _checksum.Length);
   Array.Copy(_uniqueID, 0, tmp, 68, _uniqueID.Length);
   tmp[84] = _savedState;
   Array.Copy(_reserved, 0, tmp, 85, _reserved.Length);
   foreach (byte b in tmp)
     uChecksum += b;
   this.Checksum = ~uChecksum;

There are a few things here to take note of. Firstly, the checksum is calculated by simply adding up all the bytes so this is a lot of lines to do really not that much work. The second is the unary bitwise NOT operator ~ (tilde) as this performs a one’s complement NOT operation on the checksum.


If you’re interested in programatically manipulating VHD files this post might help you get started and I would be interested to hear from you if you do something interesting with virtualisation. I may someday finish my VHD project and make a bootloader and if that day comes I’ll post it for download on this site!