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.
After a quick installation of the Hex editor plugin, I was in luck
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.
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!
public const int writeCacheType_None = 0;
public const int writeCacheType_Server = 1;
public const int writeCacheType_ServerEncrypted = 2;
public const int writeCacheType_RAM = 3;
public const int writeCacheType_ClientHD = 4;
public const int writeCacheType_ClientHDEncrypted = 5;
public const int writeCacheType_RAMDisk = 6;
public const int writeCacheType_ServerHDPersist = 7;
public const int writeCacheType_ClientHDPersist = 8;
public const int writeCacheType_ClientRAMwithOverflowOnHD = 9;