NCP VPN not quite Windows 7 compatible

I got so frustrated with the NCP VPN client software, specifically a recent update, that I decided to let my frustration out by writing about it.

 

For a long time I used the, IT approved, Cisco VPN client to access our corporate network. And as the OS technology moved along, so did my systems, meaning Vista, Windows 7, and 64-bit. While, for the most part, our IT approved systems remained to be only 32-bit XP. Cisco, for some reason, maybe they are representative of IT organizations as whole, was late to support Vista, was late to support Windows 7, and for the longest time never supported x64.

The only Cisco compatible alternative on Windows 7 x64, was the NCP VPN client. But, at a cost, $144, per machine, very expensive.

I recently read that almost 50% of Windows 7 machines are 64-bit, and I recently read that Cisco announced VPN client support for x64 on Vista and Windows 7. I am sure this is not a coincidence.

But I digress, this post is not about Cisco, it is about the NCP VPN client.

 

Where to start?

The NCP software is intrusive, every time you login it shows a splashscreen, and the splashscreen remains topmost, blocking anything behind it, until it closes, by itself. I contacted NCP support, complaining about the intrusion, and they told me that it is necessary to run their software at login so that they can validate the license. I replied that validating the license need not happen at every login, and certainly should not interfere with my system. They said I could search the internet and find out how other people disabled their software.

This means a few things to me; they do not value usability, they acknowledge there is a problem, yet they do not offer a solution.

Imagine if every application you install on your system decides it is a good idea to show a splashscreen when you login.

Here is the splashscreen that pops up on every login:
NCP.Splash

In case you are wondering how to disable NCP from running at startup, they install three user session startup entries under [HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Run], delete or rename them

 

While we’re on the topic of usability, this application’s UI was probably not designed by Windows developers, or certainly not somebody that knows anything about standard Windows user interface design and principles.

In the main UI, shown below, how do you connect, where is the connect button, do you click the red button, no you need to click the gray area next to the red button. They probably though it looks cool.
NCP.UI.1

 

Every time you login the application starts and shows its UI. How would you normally look for options in a windows app; probably [Options], or [Tools][Options], or [File][Options]. No, you need to click on [View][Autostart][No Autostart], what does the [View] menu have to do with [Autostart]?
NCP.UI.7

And in case you were wondering, no, disabling autostart does not disable the splashcreen.

 

So what is it that made me mad enough to write this post?

I received an email that a new version was released, and the software offers a built in check for update mechanism by clicking [Help][Search for Updates]:
NCP.KB.vs.MB

How big is that update? 23.792 kByte, really, 24 kilobyte, or what is a lowercase k in kByte? Or is that really 23,729 KB as in 24 megabyte?
NCP.KB.vs.MB.1

Downloaded the update, now let’s apply it:
NCP.Reboot

And then the Windows Program Compatibility Assistant pops up:
NCP.AppCompat

 

I contacted support, got an email that said no other users had reported this problem, and they asked if I am an admin on the system, but before I could respond, I got another email that said they reproduced the problem, and that I should download and install the update from the website.

Let’s download the update directly, and install it:
NCP.Update

And then the Windows Program Compatibility Assistant pops up:
NCP.AppCompat.1

 

You may think it is a problem with my system, I repeated the same steps on a second system, that is how I captured the screenshots, and I ran Microsoft Process Monitor to record what is happening.

 

As a developer, that is familiar with writing Windows 7 compatible software, I know what is going on here.

The NCP software installs:
Three startup items: NcpBudgetGui, NcpPopup, NcpRsuGui
Three services: ncpclcfg, ncprwsnt, NcpSec
Two drivers: ncpfilt, ncplelhp

 

The NCP UI process is called NCPMON.exe, and is launched by explorer, runs non-elevated, at medium IL. It is the NCPMON.exe process that downloads and executes the update.

From the procmon log I can see that NCPMON.exe called CreateProcess() to launch the installer:
Date & Time:    7/21/2010 10:01:12 AM
Event Class:    Process
Operation:    Process Create
Result:    SUCCESS
Path:    C:\Users\Pieter Viljoen\AppData\Local\Temp\NCP_EntryCl_Win32_923_17.exe
TID:    6952
Duration:    0.0000000
PID:    6856
Command line:    "C:\Users\Pieter Viljoen\AppData\Local\Temp\NCP_EntryCl_Win32_923_17.exe"

 

This will not work, the NCP_EntryCl_Win32_923_17.exe is an installer it has to “Run As Admin” (this is an InstallShield installer, and although it does not contain a Run As Admin manifest entry, the Windows Application Compatibility subsystem recognizes InstallShield installers, and automatically runs them with elevation required), this means that when you launch this EXE using ShellExecute(), or using Explorer, you will get a UAC elevation prompt, and if approved, the installer will run elevated, and the install succeed.

There is only one explanation of how NCP could ever have shipped this, their developers and QA test with UAC disabled on their test systems.

 

What about the appcompat warning after the install?

Microsoft requires that Windows Vista and Windows 7 compatible applications mark their compatibility in the installer manifest.

By inspecting the resources in the installer EXE, there is a manifest, but there is no compatibility manifest, as such, this error will always show on a Windows 7 system.

I have no explanation for how NCP could allow this to ship, ignorance?

 

It makes me mad that an ISV advertises Windows 7 compatibility, and ships software like this. It is companies like NCP that gives Windows a bad name, and drives companies like Apple, to enforce rigorous, sometimes draconian, quality and usability standards in order to protect their own brand.

Advertisements

Amazon Unbox on x64 Vista

While shopping on Amazon I noticed that they were offering the Pilot of the Showtime series Nurse Jackie in HD for free, so I decided to give it a try.
The install (version 2.0.1.95) went smoothly, and the 1.3GB downloaded also completed pretty quickly, and I watched the show.
Ok, now I wanted to stop the Unbox player service from running and terminate the tray icon application, I have no need to have it running all the time.
I went to [Settings][Preferences], and unchecked the [Run the Amazon Unbox service when Windows starts] option.

I then right clicked on the tray icon and selected [Exit], the tray application launched “Amazon Unbox Config.exe stop” application, requiring UAC elevation, and promptly crashed with the following message:

An unhandled exception of type ‘System.BadImageFormatException’ occurred in Unknown Module.
Additional information: Could not load file or assembly ‘ADVWindowsClientAppRoot, Version=2.0.1.95, Culture=neutral, PublicKeyToken=091de1773ddefdbf’ or one of its dependencies. An attempt was made to load a program with an incorrect format.

I contacted Amazon support, and they provided this response:

Hello from Amazon.com.

I sincerely apologize for the trouble you’ve had using the Unbox Video Player. From your message, I understand you received an error relating to Windows being unable to load the correct file path.

I’ve researched the issue and suggest that you update the security components of your Microsoft operating system.

Please visit the Microsoft website listed below and follow Microsoft’s instructions for updating your security components. Microsoft may require you to use Internet Explorer to access all of the functions of this page and enable Active X controls in your Web browser.

http://drmlicense.one.microsoft.com/Indivsite/en/indivit.asp

If using Microsoft’s update does not resolve your playback issue, I recommend uninstalling and reinstalling your .NET Framework.

The Microsoft .NET Framework includes a large library of coded solutions to common programming problems and a virtual machine that manages the execution of programs written specifically for the framework. The .NET Framework is a key Microsoft offering and is intended to be used by most new applications created for the Windows platform.

I hope you found this information useful.

I gave them the benefit of the doubt and tried to update the DRM components, it did not work.
I suspected I know what the problem was, and this problem reminded me of a similar problem with the Google Email Uploader on Vista x64.
My suspicions were confirmed after I used CorFlags to inspect the binaries:

CorFlags.exe “C:\Program Files (x86)\Amazon\Amazon Unbox Video\Amazon Unbox Config.exe”
Microsoft (R) .NET Framework CorFlags Conversion Tool. Version 3.5.21022.8
Copyright (c) Microsoft Corporation. All rights reserved.

Version : v2.0.50727
CLR Header: 2.5
PE : PE32
CorFlags : 9
ILONLY : 1
32BIT : 0
Signed : 1

CorFlags.exe “C:\Program Files (x86)\Amazon\Amazon Unbox Video\ADVWindowsClientAppRoot.dll”
Microsoft (R) .NET Framework CorFlags Conversion Tool. Version 3.5.21022.8
Copyright (c) Microsoft Corporation. All rights reserved.

Version : v2.0.50727
CLR Header: 2.5
PE : PE32
CorFlags : 11
ILONLY : 1
32BIT : 1
Signed : 1

The output indicated that the EXE file was compiled to run natively on any platform, i.e. x64 on x64 and x86 on x86, but the DLL was compiled to be x86 only.
Thus the EXE runs as x64 and tries to load a x86 binary, not allowed, causing the crash.
The CorFlags output and x64 migration is discussed in this MSDN blog post:

anycpu: PE = PE32 and 32BIT = 0
x86: PE = PE32 and 32BIT = 1
64-bit: PE = PE32+ and 32BIT = 0

To fix the problem I have to change the EXE attributes to only run in 32bit:

CorFlags.exe “C:\Program Files (x86)\Amazon\Amazon Unbox Video\Amazon Unbox Config.exe” /32BIT+ /Force

The “Force” flag is required because the binary is Authenticode signed, and after the header change the Authenticode signature is now invalid.
“CorFlags” is parts of the .NET / Platform SDK and can be downloaded from Microsoft.

After I made the changes to the EXE, I repeated the original steps, and no more crash.
I replied to Amazon with my findings, and I hope they make the necessary, and easy, changes to fully support x64.

DxO Optics Pro and Adobe Lightroom on Vista x64

I bought my first SLR camera, a Canon EOS 20D, and my first wide angle lens, a Canon EF-S 10-22, several years ago. Amongst the many articles and reviews I read, online and in magazines, I came across a product called DxO Optics Pro, a product that would supposedly correct, amongst other things, lens distortion. This seemed like the perfect tool to help me with my wide angle pictures that looked very “fishy eyed”. And since DxO, then version 4, was receiving good reviews, I decided to trial the product. In those days the DxO licensing model was to pay per camera body and per lens module, not a cheap investment, but I really liked the results and so I purchased the product.
Not too long after I purchased DxO, they changed their licensing model, and instead of paying per module, they came up with a Standard and an Elite product, with the distinction being the camera bodies that are supported. The Elite version typically supports more high end cameras, I am sure there is no technical difference in the calibration techniques, this just seemed like a way to get more money from professionals that own high end cameras.
In the mean time I switched to using Adobe Lightroom version 1, and DxO fell in disuse. Every now and again I did come across an article or forum post with less than flattering reports of the poor product quality in DxO version 4.5, and very poor quality in version 5. The other thing I read, and confirmed with DxO tech support, is that DxO did not support x64 editions of Vista, and since I had switched to Vista Ultimate x64 edition, this would be a problem.
I switched from taking mostly JPG images to mostly RAW images, and manual correction in LR became very time consuming, so I was again interested in DxO. By now I was using LR 2.2 x64 edition, and by now DxO 5.3.2 did support Vista x64 editions. I purchased an upgrade for DxO, I bought the more expensive Elite edition, since I have dreams of one day owning a 5D Mark II.
In standalone mode DxO 5.3.2 worked great, but the integration with LR was not so great. The problem is that DxO does not support integration with the x64 edition of LR, when calling DxO from x64 LR nothing happens. The DxO installer is also not fully x64 compatible, it creates a start menu shortcut to the “DxO Download Manager v5”, but it sets the path to “C:\Program Files\DxO Labs\DxO Download Manager v5\DxODownloadManager.exe” instead of “C:\Program Files (x86)\DxO Labs\DxO Download Manager v5\DxODownloadManager.exe”, obviously a hardcoded path instead of dynamically discovered path.
Before I get to DxO, I think Adobe should have supported in-process DLL based plugins in LR, just like they do with Photoshop. For whatever reason this type of suggestion seems to make Adobe very uncomfortable, and they go to great lengths to defend their position, reads more like marketing firefighting, and say why the LUA based scripting and external process launching is so much better than plugins, at least when compared to Apple Aperture. I am a software developer, there is no way that anybody can convince me that a scripting language or launching an external process is better, or as good, as a native DLL based plugin with a rich integration API.
So how does DxO integrate with LR in light of the lacking plugin model? When you edit an image using an external editor, LR launches the editor with the image path specified on the commandline. LR provides three options for what file is passed to the external editor; the original file, a copy of the original file, or a copy of the LR processed version of the file. The problem is that when the file is a RAW file, LR only allows a copy of the LR processed version of the file to be passed, and this processed file is useless to a RAW editor.
DxO, being a RAW file processor, obviously needs access to the original RAW file, and they go about it in a clever, but cumbersome way. LR allows for configuration of the file type and file name of the new file it generates, and DxO exploits this file naming scheme to infer the original filename. E.g. the original RAW file is called Test.CR2, LR creates a copy of this file and names it Test-Edit.TIF, DxO infers the original filename is Test.CR2, opens Test.CR2 as the input file, and uses Test-Edit.TIF as the output file.
DxO can run in one of two modes; “plugin-in” mode (their spelling, not mine) or normal mode. When launched by LR, DxO runs in plugin mode. In plugin mode DxO only allows processing of the images passed in on the commandline, and the output processing automatically replaces those same input files. 
Since DxO does not have a way of explicitly launching in plugin mode, they infer the mode by interpreting how they are being launched. DxO looks at their parent process, and if the parent process is called Lightroom.exe, and the Lightroom.exe has version information that looks like LR, then DxO automatically enters plugin mode.
So why does DxO not work when launched from the x64 edition of LR? When launching DxO from x64 LR the DxO process starts and immediately terminates without showing any UI. It appears that DxO fails to determine information about the parent process when the parent process is a x64 process. I am speculating, but this is probably related to the technique that DxO is using to determine information about the parent process. Typically one would use the PS API or ToolHelp API’s, along with NtQueryInformationProcess(), but when mixing x86 and x64 process types, they do not provide consistent information, and extra handling is required by using IsWow64Process(). A more portable, but less reliable, alternative is to use WMI. DxO is not a native application, it is written in .NET, presumable C#, but it apparently still suffers from some x64 related problem.
So how do we solve the problem? You can install both the x64 and the x86 editions of LR on your x64 system, and when you want to work with DxO you can use the x86 edition of LR. This however is not very convenient. My solution was to create a x86 proxy process that looks like LR, is discoverable by DxO, and convinces DxO to enter plugin mode. LR is then configured to launch the proxy process instead of DxO, the proxy process launches DxO and passes the same commandline parameters as passed by LR to DxO, waits for DxO to terminate, and returns the exit code to LR.
Instead of inferring the mode of operation by looking at attributes of the parent process, it would have been much simpler, and it would have avoided the x64 problem, if DxO had a stub executable that always launched in plugin mode. And, it would have been even better if LR supported DLL based plugins with programmatic access to image information instead of inferring it. But, DxO would then have had to write a native x64 DLL, and if they can’t even write WoW64 compatible x86 code, I don’t know if that would have been a solution.
So how did I figure this out? 
At this point I have to remind you that I have absolutely no connection with DxO, nor insight into the coding of DxO, nor did I reverse engineer or disassemble DxO, my analysis and solution is purely based on observing LR and DxO behaviors by using Microsoft Process Monitor.
I compared the behavior of DxO on a x86 system with the behavior on a x64 system, and I noticed that on the x86 system the DxO process opens the LR executable file on disk. Looking at the call stack I noticed that DxO calls the.NET runtime calls the GetFileVersionInfoW() API. On the x64 system DxO never attempts to open the LR executable. I installed the x86 version of LR on the x64 system, and noticed a similar behavior to the x86 system. 
I created a C++ project in Visual Studio 2008, and wrote code to take the input commandline parameters and call the DxO executable with the same parameters as passed in by LR. I built a x86 binary, renamed the output file Lightroom.exe, and when I run “Lightroom.exe c:\test\test-edit.tif”, DxO would open in plugin mode, but would not load the original test.cr2 file. I added version information to the proxy project, and matched the version information contents to that of the real LR binary. Repeating the test, DxO now believes that it was called by LR and it opens in plugin mode and it finds the correct RAW file.
The source and binary file is available here
Please remember that I provide no warranty at all, I did minimal testing, so use at your own risk.
To install simply extract, rename DxOProxy.exe to Lightroom.exe, and change the LR configuration to point to the proxy Lightroom.exe instead of the DxO binary.
In closing, and in light of my previous post related to my trouble with the Google Email Uploader on x64; with all the available programming documentation, and free compilers, and free virtualization testing environments, why is it so difficult for some ISV’s to produce quality and compatible software?

Google Email Uploader on Vista x64

I am currently importing a few thousand email messages from Outlook 2007 to my email account hosted on Google Apps. Google provides an Email Uploader utility, and it is easy to use, but getting it to work with Outlook 2007 on Vista x64 was less than trivial.

The utility installed fine on my Vista x64 system, but it found no mailboxes to import. A little research showed that several other people using Vista x64 and Outlook 2007 have exactly the same problem.

Since Google kindly publishes the source for the tool, I decided to have a look. Turns out it was a relatively simple fix to get it to work.

The main application is a C# .NET application, with the build properties for the target set to “Any CPU”. This means that on a x86 / WIN32 system it will be a 32bit process and on x64 / WIN64 system it will be a 64bit process.

The problem is that the application also uses two mixed mode DLLs, and these DLLs are compiled for x86 / WIN32. When running the main EXE on Vista x64, the process is a 64bit process, and that fails to load the 32bit DLLs. The fix was simple, change the build target from “Any CPU” to “x86”.

I also had to fix a couple other small things in order to get the “Release” build to compile correctly. The DLLs are written in C++, but for some reason the developers used .MH and .MCC extensions instead of the standard .H and .CPP extensions. The “Debug” build had set custom build properties for .MCC files, and associated the files with the C++ compiler. Once I did the same for the “Release” build, the project compiled.

The last change was to set the Outlook import DLL linker options to delay load MAPI32.DLL.

You can download the binaries from here, simply extract and run.
Please remember that I provide no warranty at all, I did minimal testing, so use at your own risk.

I hope Google makes these easy changes to the main source branch so future official versions also support Outlook 2007 on Vista x64.