Detecting registry virtualization

c#-2.0registryuacvirtualizationwindows 7

I have a set of C# (v2) apps and I am struggling with registry virtualization in Win7 (and to a lesser extent Vista).

I have a shared registry configuration area that my applications need to access in HKLM\Software\Company… Prior to Vista, everything was just written to and read from that location as needed.

The code appropriately detected failures to write to that registry key and would fall back appropriately (writing to HKCU instead and notifying the user that the settings they had applied would only affect the current user).

In Vista, registry virtualization broke all of this because the access check we were using for the HKLM write would "succeed" silently and virtualize to HKCR\VirtualStore\Machine… instead. In this case, the user would think that they had saved machine-wide configuration, but had instead only written to the virtual store.

Sadly, even attempting to enumerate the permissions on the HKLM reg key explicitly returns results indicating that the user has access whether they do or not.

When we added Vista support, the workaround we used was to perform a probe write to HKLM… and then check in HKCR\VirtualStore\Machine… for the same value and note that virtualization had occurred if the value was found.

Win7 seems to have broken this (again) because queries against the explicit virtual location (HKCR) now show merged results from the HKLM location even if the write was not virtualized.

Does anyone have any suggestions for working around this?

Constraints:
– I need a solution that works without requiring elevation (when I don't have administrator level permissions I will fallback to a per-user configuration in HKCU but I need to be able to detect this case reliably).

  • It needs to work with a v2 C# app (One option I have seen for C++ code is to embed a manifest which disables virtualization for the .exe but I haven't been able to do that in C# V2 see disable folder virtualization in windows).

  • It needs to work without an "installer" (this precludes the ability to disable virtualization on the registry key that we need ala the REG FLAGS… command).

Best Answer

This is an excellently put question, +1 (Why is it community wiki, it deserves points!)

In general, there are a set of rules (which [as you've run into] will vary over time) which control whether UAC [and thus implicitly Registry] virtualization are in play.

Some salient parts of the Registry Virtualization rulesets documentation in MSDN are:

  1. [as jeffamaphone says] if the manifest has a requestedPrivileges/requestedExecutionLevel set, it's turned off. You dont seem to have ruled out adding a manifest, so can you please indicate why this won't work for you? (You say "I haven't been able to do that in C# V2" - there is an Add Item option to add an application manifest file, and that's available in VS2005)
  2. if the exe is running 64 bit, its off by default
  3. if it's not an interactive process (such as a service, or hosted in IIS etc.), it's off

If you're not in a position to influence any of the above, which is the ideal, and you thus want to detect whether UAC virtualisation applies in the current context, use this answer to a what might at first not appeat to be a related question. (Obviously you'd still need to decide whether it applies to the specific key you're operating on, which is a moving target which you obviously wouldnt want to implement code that needs to track changes if it can at all be avoided - but in most cases it should be relatively clear.)

Related Topic