If you’re like me, you enjoy a good challenge. One thing I’ve always been interested in with regard to PVS is exactly what is in the .PVP file. From various whitepapers and blogs I’ve read over the years, I understood it to be a collection of outside of the VHD, as PVS doesn’t do anything magical with the VHD files – they’re standard, true to form honest to goodness VHDs, per the specification. Awhile back, I saw this post and a comment from Nick Rintalan caught my eye.

And while there is a header and footer in the VHD, it’s not PVS-specific and I’ve confirmed we don’t extend the header or footer…it’s simply the header and footer used in all dynamic disks according to the PVS [sic] spec defined by our friends at MSFT.

That means that PVS specific information must be stored externally, which makes sense. So, naturally, my first step was to start digging with NotePad++ first.

Viewed as plain text, you can see this is a binary format

After a quick installation of the Hex editor plugin, I was in luck

Data revealed in Hex

Seeing this, I figured there was a clearly defined structure, which makes sense, given that they are always 528,896 bytes. My next stop was on to JetBrains DotPeek, to take a look at how exactly PVS reads the file itself. I knew PVS has several interfaces (SOAP, MCLI, PowerShell) so I decided to start at the StreamProcess, but being somewhat limited in C++ experience, I moved on to the Mapi DLL which is in C#. After a bit of digging through the assemblies, I struck some pay dirt.

Header and footer structure

From there, it was only a matter of presenting it in a meaningful manner. I spent some time in the airport poking around classifying some of the properties or reformatting them to be slightly more helpful. What has come out of that, so far, is PVS DiskUP. The source code is available on GitHub if you’d like to compile this and run it yourself, or download PVS DiskUP 1.0.

There may come a time when I get bored and continue deciphering the structure, such as adding support for readable write cache types and such, but for now, I’ll leave that to the readers! Check out MapiConstants.dll, clone the Git repo and see what you come up with. If you’d like to be a contributor to the repository, please tweet me!