Thursday, December 16, 2010

WPF - Porting applications to 64-bit (WOW64)

Many of the WPF projects are technology upgrade projects. After advent of WPF, everyone wants to get rid of old Win32 based display to cool WPF display with rich graphics. It is not just an upgrade of technology from Winform to Windows Presentation Foundation, but it is also upgrade in the underlying hardware architecture. New operating systems are 64-bit operating systems. While developing applications for these new operating system, we should be aware of the differences in the frameworks because of the architecture.

So desktop applications are going rich (using WPF) and they are being 64-bit. They will eventually be causing phase-out for 32-bit desktop applications. It also happens that these systems are not rolled off in a single shot. They are retired gracefully. I have even seen these systems co-exist for some duration before the old system is gotten rid of completely. So we have our 32-bit and 64-bit systems running on a 64-bit operating system.

Now the main question which might arise is, why should we go 64-bit. There are several benefits of developing 64-bit application. The maximum number for default thread pool thread increases from 1024 to 32768 in .net framework 4.0. 32-bit applications have a default address space limitation of 2 GB so going 64-bit increases the available address space for our applications.

When you look at Task Manager, you would find a few processes with *32 as part of their names. What is that?? Basically they are 32-bit processes running on 64-bit Windows. They are given special status in 64-bit OS and they are handled differently than their 64-bit counterparts.

How to develop 64-bit applications:
When we develop WPF applications, we can specify the intended platform for our application. Just take the properties of Startup project and go to Build tab. There are multiple options available for Platform Target. You can select the platform target of your choice. It can be 32-bit (x86), 64-bit (x64), Itanium or Any CPU (architecture-neutral). Here Any CPU is an interesting option. This is basically leaving the decision for run time. If the application is being run a 32-bit architecture, it would run as a 32-bit system, otherwise it would be running as per the architecture of the runtime. It is also possible that we have different target platform for Debug and Release configuration but that is rarely the case.

There has also been a little debate in the .net developer community about which option should be the default one. I would recommend reading this post discussing about why Any CPU should not be the default option. Currently, I find x86 as the default option for WPF application (.net 4.0) in VS2010 Ultimate.

Handling of 32-bit applications by 64-bit Windows Operating System:
Windows OS handles 32-bit applications with WOW technology. This is acronym for Windows-32 on Windows 64. This is basically a 32-bit OS emulator for 32-bit applications running on 64-bit Windows Operating System. Its main purpose is to create an artificial environment for 32-bit applications so that they could run on 64 bit Operating Systems without any changes. I have seen people using both WOW64 and WOW. I don’t know what is the official name. In this post, I have noticed myself using both. But wherever you see it, now you should know that I am referring to the same thing. . Basically WOW is the similar layer in 32-bit Operating Systems for 16-bit applications. So I would recommend using the term WOW64 in order to understand the desired architecture as 64-bit architecture.

As is evident from the figure above, it is just a compatibility layer for 32-bit operating systems.

Mapping System32 folder to sysWow64 folder

If a 32-bit application requests access to the system32 folder, file system redirector redirects the request to sysWow64 folder instead. This folder contains the 32-bit versions of dlls. In case we want to bypass this direction, we should be usign %windir%\Sysnative instead.

Registry Redirection:
Wow maps all Registry operations to Wow6432Node. When a 32-bit app creates, updates or deletes a registry key, all of these operations are mapped to Wow6432Node by default by WOW. This redirection is performed by a special component of Wow64, called Registry Redirector. This copying of registry values is called Registry Relecton or Registry Mirroring.

This is a special pain-point when 32-bit and 64-bit application co-exist on the same machine. Both of these applications would be specifying same registry values to access the relevant registry keys. But since WOW maps the operations to Wow6432Node, the 64-bit application wouldn’t be able to find those registry keys. We have to specially specify Wow6432Node in registry path for 64-bit applications if we are planning to use same registry values for both. Later, when 32-bit application is phased off, we need to make sure that we have updated the path for these registry keys. We also need to make sure that we have tested the system thoroughly for this change. This is basically an observed behavior for one of our application. As a matter of fact, Windows is documented to be mapping /mirroring registry keys to Wow6432Node registry folder. In .net framework 4.0, this problem is specially addresses by providing special OpenSubKey support in RegistryKey class. Here we can specify if we want to get this value as a 32-bit application or 64-bit application. If we get it using 32-bit application, it would be using Wow64 in order to get the value, otherwise it would directly get the value of the registry key.

HKEY_LOCAL_MACHINE\Software is mapped to HKEY_LOCAL_MACHINE\Software\Wow6432Node.

Program Files Directory:
A special program files directory is also created for 32-bit applications in the directory where OS is installed (Generally C:\). This is available as Program Files (x86).

IsWow64Process Function
We can also determine if an application is running under WOW64 technology using IsWow64Process function.

Additional properties in Environment:
If we are building our application for a particular platform or Any CPU, we might still want to determine if the current process is a 64 bit process or not. There are two additions is Environment to determine:

Whether it is a 64-bit Operating System:

Whether it is a 64-bit process:

No comments: