Sunday, January 24, 2010

Windows Vista Update Problems with Patch 955430

Today I took a look at some performance problems on my wife's laptop running Vista x64. Since she installed Skype she has been running into problems where IE 8 locks up. It turns out this is a well documented problem with a patch. But, along the way I noticed that Windows Update was having problems installing KB 955430. I looked at the Windows Update history and noticed this patch had failed to install since June 14, 2009! This is a brief overview of how I diagnosed the problem and resolved it.

The error reported from Windows Installer was 80070020, which indicates that another process is using the file. The Windows Update help recommeded to try 2 things: 1) Install in safe mode with Networking enabled ad 2) Start in selective startup mode without any other non-Microsoft apps or services started.

I tried the Safe Mode route first. However, Windows Update does not run in Safe Mode, not quite the best suggestion from Microsoft. So then I downloaded the patch to run it by hand. Rebooted in Safe Mode, and received the error that Windows Installer does not operate in Safe Mode either.

Next I tried the Selective Startup option. Even though I removed all non-Microsoft services from starting, Mcshield continues to start up. However, this was not the problem. Trying Windows Update from this mode I ran into the same 80070200 error. I tried the downloaded file, also to no avail.

Next I tried going straight to Vistas SP2. I had read that 955430 was a prerequisite, but since I was having so many problems installing it, tried anyway. The first thing SP2 does is attempt to install 955430 - no dice!

I looked around on the Internet and Windows Support to no avail, so I decided to do some digging with the Sysinternals utilities 'Process Explorer' and 'Process Monitor'. Process Monitor was a champ. By watching the timing of the installation failure with the events being recorded I was able to limit the problem to about a 7 second time period. I narrowed down the processes involved to:
wusa - The Windows Update app
TrustedInstaller - the process that operates on the package files
wemgr - Windows Error Manager
svchost - Playing a supporting role

By identifying where the error occurred and working backwards I discovered the root of the problem was with TrustedInstaller trying to create the file: C:\Windows\servicing\Packages\Package_1_for_KB955430~31bf3856ad364e35~amd64~~6.0.1.18005.cat
The error from Process Monitor is: Sharing Violation, however no other process is holding a handle to the file (according to Process Explorer).
Also, it turns out the file already exists. Hmmm. It is owned by SYSTEM, but only the user TrustedInstaller has Full Control privileges. Next I checked the process ownership for the Windows Installer service. It was SYSTEM. Now things are starting to make sense, the file cannot be overwritten by the Installer process because it is running as the wrong user!

I could not (easily) change the ownership of the Windows Installer service. So instead I tried a different tact, removing the existing package files. The problem is that only the TrustedInstaller user had full control to delete, move or rename these files. Hmmm. I could not change the privileges, because that option was grayed out. However, I could Take Control of the object by my own user account. Then I could add a new permission group for my own user account, and give myself Full Control. Viola! Now I moved the files to a backup directory (in case things went bad). Tried installing the patch again using Windows Update and presto - 955430 was installed.

Boiling this down into the minimum steps:
1 - Use Process Monitor to determine which file is causing the problem; Look at Sharing Violation errors from TrustedInstaller.
2 - Locate the file to see if permissions are the cause.
3 - Take Control of the file(s) by assigning Ownership to the current user account with administrator privileges.
4 - Set privileges on the file by creating a new privilege group for the current user with Full Control.
5 - Move the files to a backup location.
6 - Install the patch using Windows Update.

Good luck!

Friday, January 1, 2010

Regarding browser proxy settings for plugins

My UML professor, Dr. Fu, asked a question regarding Browser Plug-in use of a browser's proxy settings. It seemed like an easy enough question to answer, but before I knew it I was reading source code, so I'm not sure how obvious this info is. This may be the reason that so few plug-ins comply with a browser's proxy settings. I did a bit of research and decided to use it for my first blog post.


First I wanted to look at the Firefox proxy settings. It wasn't clear what 'Auto-detect proxy settings for this network' actually used to determine the proxy. Neither reading the Firefox help nor Googling, answered the question.
It turns out that all major browsers use a protocol called WPAD (Web Proxy Autodiscovery Protocol) that uses DHCP or DNS protocols to identify a URL that contains proxy details. More information is available here: http://en.wikipedia.org/wiki/Web_Proxy_Autodiscovery_Protocol
This file is formatted based on the Proxy Auto-Config (PAC) file standard (http://en.wikipedia.org/wiki/Proxy_auto-config). You can also specify the URL to this file directly in the 'Automatic proxy configuration URL' in the browser's proxy settings.



Now onto the real purpose of this post...

On a Window's platform it's pretty easy to get the system's proxy settings (which are also the IE proxy settings). You can use either WinHttpGetIEProxyForCurrentUser() or InternetOpen() from C/C++ - which is a good language choice for a Plugin.

An example of WinHttpGetIEProxyForCurrentUser() is located here: http://stackoverflow.com/questions/202547

An example of InternetOpen() is located here: http://support.microsoft.com/kb/226473

These are not good options for most browsers, such as those based on Mozilla. Instead other APIs are required such as NPAPI or XPCOM.

The current preference is NPAPI, with updates to this API as recently as early '09. It includes new options to remove dependency on browser specific XPCOM APIs (more on that in a second). To cut to the chase, the new API is NPN_GetValueForURL() (in npapi.h). Use this with the NPNURLVariable parameter set to NPNURLVProxy. An example of using this API for Cookies is here: http://forums.mozillazine.org/viewtopic.php?f=27&t=1233835

According to this post (http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6796470), the NPAPI enhancements are available as far back as Firefox 3.1.

As for the XPCOM API, it was provided by Firefox to provide more access than available through the initial versions of NPAPI (https://developer.mozilla.org/En/XPCOM_API_Reference). However, it was browser specific, and only available in Firefox. According to this post, it is deprecated following Firefox 3.6: https://lists.ximiam.com/pipermail/moonlight-list/2009-October/000628.html

The XPCOM API provides a set of nsIProtocolProxyService APIs (https://developer.mozilla.org/en/NsIProtocolProxyService). These provide access to a number of browser proxy settings. Here's an example of using the XPCOM API from both C++ and a script: https://developer.mozilla.org/en/Creating_XPCOM_Components/Using_XPCOM_Components#Finding_Mozilla_Components

Note that both the NPAPI and XPCOM APIs provide info about the resolved proxy settings. This means that if Automatic proxy settings are used, the values returned via these APIs are the actual proxy server, rather than a link to a PAC file.