Thoughts on Windows Vista

I just finished upgrading InfoStore to version 3.2, which is supposed to be fully compatible with Windows Vista. In order to do that, I had to take a good look under the hood of the new operating system. There are several major changes that were introduced, and they are generally an improvement, at least in the area of system security, but they certainly require programmers to acquire a new mindset.

The first problem to overcome was folder and registry virtualization. The basic idea is that from now on programs are not supposed to run with administrative privileges (unless they really have to), and they are not supposed to write under certain system folders, like Windows or Program Files. That’s a good thing, since in the past programs had access to anything and everything and that created a lot of problems. Not to mention malicious programs or viruses. InfoStore doesn’t need access to Windows or Program Files, but it does store library information under All Users\Application Data (CSIDL_COMMON_APPDATA), which was till now a suggested folder to use for applications to share data across user accounts. In Vista however, this folder is also off limits and requires administrative privileges. Don’t ask me why, in my opinion it should have been left accessible to invokers, but I’m sure Microsoft had a good reason for the change. In any case, this created a problem. The library installer runs with administrative privileges and is thus allowed to write directly to CSIDL_COMMON_APPDATA. But InfoStore doesn’t run with administrative privileges and is not allowed access to CSIDL_COMMON_APPDATA. In order to ensure that older programs that have been created with access to things that they shouldn’t have access to continue to run, Microsoft introduced folder virtualization. So when InfoStore tries to access CSIDL_COMMON_APPDATA, it’s actually redirected and reads from a virtual store folder. This actually took me a while to figure out, seeing that both programs (the library installer and InfoStore) were reading from exactly the same folder but were returning a different file list. Odd indeed!

The problem is that when the library gets updated by the installer, it gets updated in the real CSIDL_COMMON_APPDATA, but InfoStore continues reading the contents of the virtual store folder and doesn’t see the updated files. So library updates don’t work.

The only solution was to change the folder where InfoStore keeps the library file information. So from now on the files are kept under CSIDL_COMMON_DOCUMENTS. Only on Vista though, on the older versions of Windows there was no need to change the folder.

Of course to be able to differentiate between CSIDL_COMMON_DOCUMENTS and CSIDL_COMMON_APPDATA I needed to be able to determine what version of Windows the program is running on. And here we get into another problem. GetVersionEx doesn’t always return the correct Windows version. Every Vista program is supposed to have some new XML entries in the manifest that indicate whether it should run as administrator or invoker (a normal user). If these entries are present, Vista runs the program directly without assigning it any compatibility options. But if those are not present, Vista will most likely run the program under XP compatibility and thus GetVersionEx or even direct reading of the version from the registry will return 5.1 instead of 6.

The problem is that the library update programs that have already been distributed and that use NSInstall.dll to install the libraries don’t have the new XML entries. So even if I include the new manifest with the new version of NSInstall.dll that actually does the work of library updating, Vista will run it as under Windows 5.1. Thus it will think that it should still be using CSIDL_COMMON_APPDATA instead of CSIDL_COMMON_DOCUMENTS.

There are several workarounds for getting the actual version of Windows from the system, but my favorite, and the one I used, was checking for new functions that has faithfully been introduced in the kernel with every Windows update. Since I only need to determine whether we’re running Vista or not, I used:

GetProcAddress(GetModuleHandle('kernel32'), PChar('GetLocaleInfoEx')) <> nil

This is Delphi syntax, by the way. GetLocaleInfoEx is a new function that has been introduced with Vista. So now we are all set! Of course the program upgrader needed to be able to copy all the current user settings from under CSIDL_COMMON_APPDATA to CSIDL_COMMON_DOCUMENTS, but that wasn’t much of a problem. Now that I’m thinking about it, I could have just made it uniform for all versions of Windows to use CSIDL_COMMON_DOCUMENTS since the upgrader copies the settings anyway, well, the upgrade is not released yet, so maybe I still will!

There were some problems of visual nature, dealing with Delphi’s hidden application window, which prevented the display of the main program window contents in the Flip 3D and taskbar previews. There’s a very nice article that explains the issues and offers some solutions. Actually I just heard that Delphi 2007 is available, and that it fixes all those issues. I should think about upgrading. Although I suppose it’s easier said than done, since probably a number of components and methods I used will not be compatible and I’ll need to do lots of adjusting work. Maybe I’ll wait until I’ll be working on the next major version of the program.

Well, along with all the above mention fixes there were also a few access violation problems that were eliminated, so things should be running much smoother now. And really, if you got through this entire article and are reading here, then you have a lot of patience for reading boring stuff. Congratulations! Patience is a virtue!

    Leave a Reply

    *