Thursday, May 28, 2009

Registry Weirdness, UAC and the Vista Virtual Store

It appears that two different can see a different view of the registry content.  I seem to recall seeing mention about registry values potentially being seen differently by elevated and non-elevated applications when UAC is active.

In this case, ProcessInvocation.exe sees the following value for a particular key:  (which is wrong!)


But regedit.exe sees the following value:  (which is correct!)

C:\Program Files\Gallio\bin\TDNet\Gallio.TDNetRunner.dll

The first value was used for local development of Gallio v3.0.6 but I deleted that value!  In fact I deleted it a week ago and I don't think I've recreated it since (because Gallio v3.0.7 uses different keys).

The second value was set by the Gallio v3.0.6 installer (uses the old key).  This is the value I expect to see globally.  All interesting applications were closed at the the time of installation.

So why are some applications seeing the first value and other applications seeing the second value?

No, this is not a simple question of refreshing or shutting down applications.  I have shut them both down and tried again and the weird view remains persistent!

Next up, reboot.  Argh.

After the Reboot...

Same behavior.


Here's what I found when I searched the registry for the incorrect value:  (SID masked)


Whoa.  So at least I'm not dreaming.

The UAC Virtual Store

On Vista, normal users are forbidden from writing to certain folders (like %ProgramFiles% and %SystemRoot%) and into the HKEY_LOCAL_MACHINE part of the registry.  Even local administrator users are forbidden from writing into these folders, unless elevated.

Well, not quite.  As a compatibility feature, instead of generating an error, a write by a non-elevated application running as a local administrator may be redirected to a Virtual Store on the file system or in the registry as appropriate.  The Virtual Store functions as a shallow per-user overlay of protected parts of the file system and registry.  Each user has a separate Virtual Store from all other users so misbehaving old-style applications can keep pretending they have write access to places they don't but the impact remains local to the user.

The file system Virtual Store is in %LOCALAPPDATA%\VirtualStore.  Here are a few things that mine contains:

  • _vimrc files
  • *.pyc files created by GNU Solfege
  • Reflector.cfg
  • Trillian crash dumps and user data (this explains a few oddities I've seen!)

The registry Virtual Store is in HKEY_CURRENT_USER\Software\Classes\VirtualStore.  Here are a few things that mine contains:

  • Old obsolete registry keys I created for debugging that got me into this mess.
  • A EULA key for Acrobat Reader.  (Nowadays I use FoxIt Reader.)
  • Configuration for a few audio codecs.
  • An MRU list for DirectDraw (weird).
  • A flag set by my 3G wireless software.
  • Configuration for OpenVPN.

What Actually Happened

Once upon a time, I ran a little script without elevation to create some registry keys for local development.  Since the script was not elevated, the new registry keys were created within the Virtual Store.

Later on, I ran a script to delete these keys.  But in the interim I had changed the script to run with elevation.  Because it ran with elevation it did not see the keys in the Virtual Store so it left them there.

Then I installed Gallio v3.0.6 which, being an installer, created some new registry keys with elevation in the expected location.

When I tried to run a test, the ProcessInvocation.exe component of TestDriven.Net enumerated these keys in the registry, but without elevation.  Consequently it saw the old keys in the Virtual Store and got extremely confused.



Normally the Virtual Store on Vista is not a problem.  Actually it's a pretty clever solution to a serious compatibility problem.  However, if you ever run into issues like mine you might just need to learn about it so that you can delete or repair the magic virtualized content if needed.

More info:

Technorati Tags:

No comments: