Tuesday, March 13, 2007

Solution to Vista USB ReadyBoost Hang

Microsoft has released a patch for Vista that cures several problems with USB devices, including devices that hang when resuming from Sleep. Here's the solution:

Reliability update for the USB stack in Windows Vista

Finding this patch isn't particularly easy if Google is your only search engine. The knowledgebase article doesn't mention ReadyBoost at all. It comes up as the first result if you search support.microsoft.com for vista and usb, but it's on page three if you search Google for vista usb hang.

My Apacer USB thumb drive is dead, so I can't test out the patch until I order a new one.

[Update 4/25/2007]
The Microsoft Knowledgebase article has been retitled Stop errors occur on a Windows-based computer that has 2GB or more of RAM and is using an NVIDIA nForce USB controller. My computer isn't based on the nVidia chipset, but the update still fixed my hang problem, so I'm not sure why Microsoft retitled the article. I do have 2GB of RAM.

Making VC2005 Remote Debugging Work

I use Virtual PC extensively for testing older operating systems and non-standard configurations. When I have to debug configuration-related problems, I use Remote Debugging to connect to the Virtual PC instance and debug in-situ.

Before I upgraded to VC2005, remote debugging with VC++ 6 was straightforward. I updated the PATH on the remote computer to include MSVCMON.EXE, the related debugger DLLs, and the debug versions of the C runtime library and MFC. Worked great.

Remote debugging with VC2005 is more challenging. Between security problems and Windows Side-by-Side assembles, it can take quite a few steps to make everything work. Here is what I had to do.

Your debugger and Windows firewall double-team you to make configuring remote debugging as painful as possible. My first problem was to fix the firewall, since I couldn't connect to the Windows XP SP2 computer at all. I fixed this by disabling the Windows Firewall (if you are following along, don't do this unless you are absolutely certain it's okay for your environment!) Probably overkill, but simple.

My next problem was debugger authentication. This proved to be a challenge because my Virtual PC test machine is on a domain and my development machine is not. After several hours of effort, I determined that they simply were not going to agree on a trust relationship, so I disabled authentication. (Handy tip - you can do this from the command line with /noauth. Also add /nosecuritywarn if you don't want to go crazy with security prompts.)

I thought I was golden at this point. I clicked F5 to debug my executable and was told, "Could not start App.exe". So I tried to start the application from Explorer. Same result. I ran Dependency Walker to check my DLL dependencies and was reminded that I needed to update my path to include the VC2005 debug libraries for the CRT and MFC. I did so, clicked F5 again, and... it still didn't work.

Several hours and much frustration later, I had received a solid education about Windows Side-by-Side Assemblies, otherwise known as WinSxS. In order to cure "DLL Hell," Windows XP and Windows Vista provide support for an executable's manifest to hardcode the desired version of dependent DLLs. For executables created with VC2005 that are dynamically linked to MFC and the CRT, a manifest is automatically inserted into the generated executable that includes this version information.

Once this is done, Windows XP and Windows Vista become absolutely hell bent on loading the correct version of the DLLs. Trying to work around this protection is futile. None of the following "obvious" solutions work:

  • Putting mfc80d.dll in the same directory as the EXE, even if it's the correct version.
  • Including mfc80d.dll on the user's path.
  • Manually copying the appropriate directories from the \Windows\WinSxS on the development machine to \Windows\WinSxS on the remote debuggee.
After spending far too much time reading mostly useless documentation, I came across the correct solution. In your Visual Studio 2005 installation, you'll find a directory named:

\Program Files\Microsoft Visual Studio 8\VC\redist\Debug_NonRedist\x86

Inside this directory, you'll find two more directories named Microsoft.VC80.DebugCRT and Microsoft.VC80.DebugMFC. These directories must be copied to the same directory as your EXE and magically everything works right.

At this point you'd think the story is over, but it's not. Windows 2000, Windows NT and Win9x don't support WinSxS, so the manifest is ignored. To debug your application any of THOSE versions of Windows, you need to include the appropriate DLLs on your PATH (or copy the appopriate DLLs into the same directory as your EXE.) I set the path in Virtual PC to point directly to the WinSxS directories on my development machine, which were: ("duo" is the host name of the development computer, which drive C shared under the name "C")


Finally, I used the following command in my batch file to start the debug monitor:

start "" "\\duo\c\Program Files\Microsoft Visual Studio 8\Common7\IDE\Remote Debugger\x86\msvsmon.exe" /noauth /anyuser /nosecuritywarn /timeout 7200

Finally, that made everything work properly.

Tuesday, March 6, 2007

Visual Studio 2005 SP1 Update for Windows Vista Released

A little bit later than I really needed it, but Visual Studio 2005 Service Pack 1 Update for Windows Vista has been released. Get it while it's hot!