Question

(Updated after trying suggestion from David Heffernan)

I have a legacy Win32 native app (Delphi 6) that writes values the registry under the HKEY_LOCAL_MACHINE\Software\\ key. These values are later read by several other legacy Win32 native apps and a new .NET application. The .NET app is build AnyCPU so is executing as a 64 bit image. Because it was using config written by 32bit apps the .NET software was redirecting its registry reads to the Wow6432Node that the Win32 API apps actually wrote to.

None of the applications are running elevated. All applications are interactive. The account used to run the applications has explicit "Full control" of the HKEY_LOCAL_MACHINE\Software\\ registry key and it's sub-keys.

As far as I know this was not using registry virtualisation because the 32bit apps had write access to the HKLM keys they wrote to.

This scenario has worked just fine on 64 bit Windows 7 and 64 bit Windows 8 machines, but on a new Windows 8.1 64 bit machine all is not working.

Whilst the legacy Win32 app writes to the registry without errors it now appears to be getting virtualized. This can be confirmed by looking in the users virtualized registry key; I see all the written values in there.

When I look at the HKEY_LOCAL_MACHINE\Software\\ key with REGEDIT then about half of the keys I wrote are simply missing from HKEY_LOCAL_MACHINE\Software\\ but all are present in the virtualised folder.

As I understand it with a 32 bit app with write permissions there should be no virtualisation, but there is. Worse when I read the non virtualised key I see some but not all of the values that were written to the virtualised store.

Why did it virtualise the write all of a sudden, and why would the read not show all the virtualised values when I read the original key (i.e. virtualised read not working as expected)?

I presume this must be a permissions issue as if I run the app "as administrator" the keys are all there. However running elevated is not a permissible end configuration.

Update

I cleaned out all the registry settings on this machine. Both in the virtual store under HKCU, and in the shared area under HKLM. Then started again, not running elevated. This caused similar symptoms, but this time I only see 1 of the keys in the HKLM key.

I an going to write a Win32 app to enumerate the HKEY_LOCAL_MACHINE\Software\\ key in case I am being fooled by something regedit.exe is or is not doing for me when run on a 64 bit OS and will update when I have results from that. Got it its a virtualisation mismatch between legacy 32 bit WinAPI apps and new 64 bit apps. See my answer for details.

Was it helpful?

Solution

The virtualization of the registry works just the same in Windows 8.1 as it has done in Vista, Win7 and Win8. There are no changes that can explain what you report.

Are you aware that virtualization was introduced 7 years ago in Vista to help applications that could not be modified work in the face on UAC. The idea is that you fix your application to be aware of UAC, and stop running virtualized.

The thing about virtualization is that your application will write to the virtual store if running as standard user. But if you execute the application elevated then the application writes to the shared part of the registry, HKLM. From your description above it would seem that you have run the application elevated and this has written values to HKLM rather than the virtual store.

I suggest that you clean out all the registry settings on this machine. Both in the virtual store under HKCU, and in the shared area under HKLM. Then start again with your application, not running elevated. I'm confident that it will work the same way as under previous versions.

However, I am astounded that you are still trying to use virtualization as a feature. It is a crutch to aid the helpless. Don't be helpless. Stop running virtualized. Run away from virtualization.

Update

Your question edit changes this entirely. In fact you are not asking about differences between Windows 8.1 and earlier versions. You are running a different program on your Windows 8.1 machine, one that is 64 bit. And 64 bit process are never virtualized.

Again I repeat my advice that virtualization is not to be used the way you do. It is folly to rely on it this way.

OTHER TIPS

OK, Well I got to the bottom of this. David Heffernan was right the waters were indeed very muddied by having run some of these apps elevated in the past.

I wrote a small pair of test apps to isolate the issue (or rather non issue as it turns out) a Delphi 6 32 bit Win32 app that enumerated the HKEY_LOCAL_MACHINE\Software\\ key as all the other legacy apps did; i.e. ignoring the virtualization of keys. This saw all keys as if in the HKEY_LOCAL_MACHINE\Software\\ area even though they were in fact written to the VirtualStore HKLU area. This explains why all our legacy apps were quite happy.

I also wrote a simple .NET 64 bit app to test how it would enumerate the registry for the HKEY_LOCAL_MACHINE\Software\\ key. Is saw noting, regardless of view mode (32 or 64 bit). It did see everything in the virtualised registry location.

MY issue is the scope of virtualisation. its for legacy apps. Windows assumes that any 64 bit apps are not legacy apps and are doing the right thing; read virtualisation is disabled for 64 bit apps; you must do it yourself if your 64 bit app has to read values written by legacy 32bit apps that the OS is virtualising for you.

See this MSDN article for details; the pertinent bit (which I had missed) is in the section titled "Registry Virtualization Scope"

Registry virtualization is disabled for the following:
•64-bit processes.

I have modified my new app to account for the fact that since it must relay on settings written by a legacy 32 bit app; those settings may get virtualized, and hence it now checks the virtualization registry location before falling back to the un-virtualised one.

I have been plagued by the same issue and i am not using 64 bits applications. Our application is a point of sale software that uses a key in the registry common to all users to store GLOBAL information about the business application. The way we proceeded is that we combine granting the write access to that key in the HKLM/software/Store management key and subkeys so that the application does not get virtualized into the private user registry. The financial and configuration information stored there must be available to any user running our software.

On top of this, we use the reg flags command to set the dont_virtualize dont_silent_fail recurse_flag on that key and subkeys to warn Windows to stop virtualizing this key and sub key. This works very well on Vista and Windows 7 but apparently it does not work well on windows 8.1. I am getting some of my keys virtualized regardless at random apparently.

So in my case, i am not counting on virtualisation to make my program work but rather i am getting screwed by it kicking in when it is not supposed to. I am trying to find ways to permanently disable this virtualisation because my program does not need crutches to walk.

Addendum: While looking for possible solutions, i found out that if the 32 bits programs had a manifest that explains to Windows their degree of compatibility with Vista and Windows 7 that Windows stops virtualising the common registry keys and even produces the expected access error when the user does not have the proper rights to write to the common registry section of our programs. So, for versions already in the field, a separate manifest file will resolve this issue apparently and we should embed a manifest in our new releases of our software. We will still use the reg flags command to ask Windows not to virtualise the keys and to give an error when access is not granted as it should have always done in the first place.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top