Quick and dirty way of cleaning the Windows icon cache

When developing my software, sometimes I need to try a few changes to the application icon, to see which image looks better. Unfortunately, replacing the icon within the application file does not make Windows recognize the new icon when displaying a shortcut to the file: it displays the old icon no matter what: pressing the F5 key to refresh the desktop, using the shortcut Properties window to force it to use the new icon, nothing has an effect.

The problem, of course, is the icon cache: turns out that Windows keeps each icon in its memory (the icon cache), and when it needs to draw the icon, it uses the copy from the cache rather than retrieving the icon image from the original application file. It makes Windows draw the icons faster, but the negative side effect is the inability of Windows to detect the change of the icon.

The naïve approach to this problem seems to be to delete the icon cache, and thus force Windows to recreate it from scratch. Browsing the user profile folder (such as C:\Users\Username on Vista, or C:\Documents and Settings\Username on XP) reveals the file named suspiciously IconCache.db (located in the subfolder AppData/Local on Vista or Local Settings\Application Data on XP. Note that this file usually has the SYSTEM and HIDDEN attributes, so you may need to change your Windows folder settings to see this file). However, deleting this file causes no effect: Windows keeps displaying the old icon. (Which is not very surprising, because the very fact that Windows did not stop us from deleting this file kind of tells us that the file was not in use by Windows). Even restarting the computer does not help: Windows simply recreates the IconCache.db file with the old icon in it, and keeps displaying the old icon!

Nevertheless, it is possible to delete the icon cache and force Windows to rebuild it. Turns out, Windows recreates the IconCache.db file when the user logs off from his or her account. When the user logs back on, Windows loads the IconCache.db file back intro its memory. This gives us the idea when could be the proper time to delete the IconCache.db file: when the user is logged off. But how to delete the file if the user is not logged on and there is no way to start Windows Explorer or some other file management tool (such as my AB Commander, sorry for the plug, couldn’t resist :-) ) Easy: log in to another user account (such as the administrator’s one) and delete the IconCache.db file that exists in your own profile (you do use separate accounts for the day-to-day work and for the administrative tasks, do you?) Another way is to log off from your account and then connect to your computer from another computer on your LAN (you do have both a desktop and a laptop, do you? And they can talk to each other over the local network, can they? If not, what are you doing reading this blog? Just kidding…) Anyway, from another networked computer navigate to your profile over the network, delete IconCache.db, then go back to the first computer and log back into your account. This time Windows will recreate its cache and start displaying the new icon.

P.S. There is a couple of other methods of forcing Windows to rebuild the icon cache. For example, in Vista, you can change the size of the desktop icons (by right-clicking on the desktop and using the View menu), and then change it back. Or, if you have Windows XP, open the Display Properties window from Control Panel, select the Appearance tab, and click on Effect. Now change the Use large icons option, click OK, Apply to have it take effect. Then repeat the procedure to change the option back to what it was before.

The advantage of these methods is that you don’t need to log off from your account to rebuild the icon cache. The disadvantage is that Windows may mess up the layout of your icons on the desktop, and you may need to rearrange them after the icon cache is updated.

Making Vista play nice with XP on a network

While testing my software for compatibility with Windows Vista during the last couple of years I’ve noticed that Vista often does not want to play nice with other computers on my LAN. If there are only XP computers connected, everything was fine: they could see each other, I could move files between their shared folders, etc., no problems. However, should I start a computer with Windows Vista on it, more often than not that computer would not connect to others. When that happened in the past, I usually was in the middle of some other work that I did not want to interrupt, so I would just move the files using a USB flash drive and be done with it. When it happened yesterday, however, I was fed up with it and decided to get to the root of the problem.

The problem was, when I opened the Network folder on the Vista computer, I could see all other computers on the same LAN, as it was supposed to be. However, an attempt to open any of them would either present me with a login box (and no user name and password I tried would let me connect to that computer), or an error message would appear saying “Windows cannot access \\DEV. Check the spelling of the name…”, (where DEV is another computer on the LAN running XP) with the error code 0x80070035 “The network path was not found”. Pressing the Diagnose button would result in the message “DEV is not a valid host name”. Which kind of did not make sense because DEV did show up in the Network folder.

I’ve spent a couple of hours googling around and trying every troubleshooting suggestion I could find, like:

  • Is the name of the workroup correct?
  • If Network discovery and File sharing enabled?
  • Is there something to share from the Vista computer (like a folder on its hard drive)?
  • Does turning the firewall temporarily off make a difference?
  • Does rebooting the Vista computer help?

Nothing helped, the Vista computer could not connect to others. After googling some more, I’ve found the solution. (Ironically, it’s a suggestion for the Linux users, but it worked for me, too):

  1. Open the Local Security Policy console (it’s on the Start – Administrative Tools menu)
  2. Navigate to Local Policy – Security Options
  3. Locate the entry named “Network security: LAN Manager authentication level”
  4. Change the value to “Send LM and NTLM responses”

After I did that, the Vista computer magically started to recognize the presence of other computers and connect to them, just like XP computers always did.

What exactly did the policy change do? It allowed Vista to use a less strong network authentication protocol. Why was it necessary? Apparently, my router (Buffalo AirStation) that runs a variation of Linux, does not provide full support for the NTLM authentication. It is it dangerous to allow the LM responses? It would be dangerous if I allowed unknown persons to plug into my LAN and eavesdrop on the traffic (by doing that they could recover my Windows password), but no one but me is connecting to my LAN. I have to make a note to myself: when I upgrade the router, I need to try to turn off the LM responses on all computers and see if my network would work OK.

Hope this helps someone.

Update: (September 8, 2008)

If you have one of the Home editions of Vista that doesn’t come with the Local Security Policy tool, you can change this policy manually with the Registry Editor: navigate to the key HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa, and set the REG_DWORD value named LmCompatibilityLevel to 0. This is equivalent to setting the “Send LM and NTLM responses” value as described above.

How to create a shared clipboard and copy and paste text between computers with ease

(It’s been a very busy time here lately: the taxes, a new product that’s almost done, but just can’t quite get finished, and as a result, no spare time for this blog of mine. Dear Subscribers (both of you), I’m very sorry, please don’t give up on me, I’ll try to post more often here in the future. OK, I want to finish my new product first, and then I’ll try to post more often. I promise :-) ).

Anyway, today I’ll write about a neat way of creating a “shared” clipboard on your LAN, to be able to quickly send pieces of text between computers just as easily as pressing Ctrl+C and Ctrl+V.

Not sure what I mean? Suppose you have several computers connected into a LAN, and you need to copy some text on one computer and paste into another, how would you do it? For instance, most of the time I browse the Internet with my laptop. If I encounter a download link to an interesting program, I want to try it, but I don’t want to install it on the laptop itself (I’m very selective about what gets installed where), I want to download it to my test computer and try it out there first. So I need to copy the web address from the web browser running on the laptop, and paste that address into the web browser running on the test computer. If it were the same computer, the procedure would be extremely easy: Ctrl+C, then Ctrl+V, and that’s all. But if I do Ctrl+C on one computer and then Ctrl+V on another one, it does not work the way I want, because the second computer has its own clipboard, independent of the clipboard the first computer has.

To solve this problem, I need to create a “shared” clipboard. In the past I used a little utility called Netclip, that did that for me: it used a shared folder as the storage for the shared clipboard, and whenever I wanted to copy something across the network, I would press Ctrl+Alt+C, to copy, and then moved to the second computer, pressed Ctrl+Alt+V there, and that would paste the result there. It worked well for years, but then Vista came along, and Netclip stopped working with it (and it did not seem like the Netclip developers were around anymore to release a new Vista-compatible version). So I started searching for a replacement, and tried a few other similar utilities, claiming the ability to share the clipboard between several computers. Unfortunately, none of them worked well.

Finally, some time ago I encountered a free tool called AutoHotkey (it’s a pity I did not discover it earlier, it would have saved me quite a lot of keystokes). In a nutshell, Aut0Hotkey enables you to create scripts to be executed when certain keys are pressed. There are plenty of examples at their web site of the scripts doing a lot of different things, check it out!

One of the first things I tried with AutoHotkey was to write a script that would emulate the functionality of the Netclip utility.The idea was as follows: I would set up a shared folder on one my computers that is turned on most of the time. Then I would set up two hot keys, one (Win+C) to copy whatever was currently selected to a file located in the shared folder, and the second key (Win+V) to read information from that file, and paste it into the clipboard.

After looking into the sample AutoHotkey scripts, I came up with the following script to emulate Netclip:

--- begin netclip.ahk ----

path := "\\your_computer\your_shared_folder\netclip.txt"
#C:: ; Win+C

AutoTrim Off  ; Retain any leading and trailing whitespace on the clipboard.

FileDelete, %path%
if (ErrorLevel > 0 ) ; could not delete the file
{
 MsgBox FileDelete failed for %path%
 return
}

Send ^c	; copy whatever it is to the clipboard
FileAppend, %ClipboardAll%, %path%

if (ErrorLevel > 0 ) ; could not write the file
{
 MsgBox FileAppend failed for %path%
 return
}
return

#V::	; Win+V

FileRead, Clipboard, *c %path%

if (ErrorLevel > 0 ) ; could not read the file
{
 MsgBox FileRead failed for %path%
 return
}

Send ^v	; paste whatever it is from the clipboard
return

--- end netclip.ahk ----

To use this script, copy the code between the dashed lines and save it to a text file named netclip.ahk (or whatever you want to name it, but keep its extension .ahk). The only thing that you need to modify in the script is the variable path that contains the location of the shared file to be used for the storage, at the very top of the script. Make sure the shared folder you use for storage is writable from other computers on your LAN.

If you have not done it yet, install AutoHotkey on each computer, and copy the script to each computer, too  (or put it into the shared folder itself). Create a shortcut to the script, and use it whenever you want to activate the shared clipboard. If you want it to be always active, add the shortcut to your Programs – Startup folder.
Now, whenever you want to copy some text to the shared clipboard, select it just as you would for the regular copy, but instead of Ctrl+C press Win+C. To paste it into another computer, go to that computer and instead of the usual Ctrt+V press Win+V. Yes, it’s that easy :-)

It works well for me, I hope it will work just as well for you, too. Happy copy-pasting, bye till next time. I’m off to finish my new product (stay tuned!).

Giving Mint.com a try

One thing that is always scarce when running a small business is time. I’ve been constantly looking for tools and services that can automate some of the routine tasks I do, hoping that they would save me some extra time to spend on the more interesting activities. A few months ago I learned about one such service: Mint.com. The idea sounded quite interesting: you give it the login details to your online credit card and bank accounts, and it would keep track of them, giving you the high-level overviews, notifications of various events (such as when new bills become available), etc. Although it seemed somewhat risky to give a third party online service the login details to my financial accounts, the promise of the potential savings in time seemed significant enough, so I decided to give it a try.

The service was (and still is as of this writing) in a beta phase, so I expected a few hiccups now and then. To my surprise,the setup went rather smooth: after providing my login details to various bank and credit card accounts, Mint.com downloaded the transaction history for those accounts, and I could see my financial picture in one place. I liked it! When a new credit card bill became available, Mint.com would display a notification both on the online dashboard, and it would also send me an email message. That was the most useful feature of Mint.com for me, that would allow me to free myself from the regular routine of going through the bills every few days and checking their due dates. With Mint.com, I could just wait for an email notification to arrive, and when it did, I would open that online account directly, paid the bill, and forget about it till the next notification.

Well, a few minor hiccups did happen during the few months I was trying it. For example, it was supposed to automatically download the new transactions from my accounts at least once a day, but sometimes it would not update the history for 3 or 4 days. That was easy to fix by pressing the Update button on the Mint.com dashboard and force it to download the latest transactions. Sometimes it would characterize the transactions inaccurately (for example, it described payments for the web hosting service as travel expense). However, those were the minor things, and the primary function of Mint.com that I liked the most (keeping track of the credit card bills) seemed to work well.

Until last week.

Two new credit card bills arrived a few days ago and I was unpleasantly surprised to see the LATE FEE lines on each of them. Turns out Mint.com did not send me any notifications about them, even though I checked its dashboard almost daily. Now I’m stuck with two missed credit payments. Sigh…

I guess, the moral of this story is, I should not had trusted such an important procedure as keeping track of the credit card bills to a service in beta. For now, I’m going to close my Mint.com account, and set up the email notifications with each credit card company directly. Maybe I’ll give Mint.com another try when they end the beta period and start doing business “for real”.

I hope this story will help someone be more careful when trusting credit card bill payments to the third-party services.

Vista tools

(This article was originally published at the TweakUAC site.)

Version 2.1 (Updated 2008-Feb-24)

While porting our applications to Windows Vista, we had to overcome quite a few challenges related to the new security features of Vista (such as the User Account Control). We decided to make public several functions we’ve developed, to make it easier for other developers to solve such problems, too.

The functions we’ve developed are written in C++ (using Microsoft Visual Studio 2005), and packaged in the file VistaTools.cxx. Please note:

THIS CODE AND INFORMATION IS PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.

TERMS OF USE: You are free to use this file in any way you like, for both the commercial and non-commercial purposes, royalty-free, AS LONG AS you agree with the warranty disclaimer above, EXCEPT that you may not remove or modify the warranty statement and the copyright notice the file contains.

The file VistaTools.cxx contains the following functions:

BOOL IsVista();

Use IsVista() to determine whether the current process is running under Windows Vista (or a later version of Windows, whatever it will be).

Return Values:

If the function succeeds, and the current version of Windows is Vista or later, the return value is TRUE.

If the function fails, or if the current version of Windows is older than Vista (that is, if it is Windows XP, Windows 2000, Windows Server 2003, Windows 98, etc.) the return value is FALSE.

BOOL IsWow64();

Use IsWow64() to determine whether the current 32-bit process is running under 64-bit Windows (Vista or XP).

Return Values:

If the function succeeds, and the current version of Windows is x64, the return value is TRUE.

If the function fails, or if the current version of Windows is 32-bit, the return value is FALSE.

NOTE: While this function is not Vista specific (it works under XP as well), we include it here to be able to prevent execution of the 32-bit code under 64-bit Windows, when required.

HRESULT
GetElevationType( __out TOKEN_ELEVATION_TYPE * ptet );

Use GetElevationType() to determine the elevation type of the current process.

Parameters:

ptet – [out] Pointer to a variable that receives the elevation type of the current process.

The possible values are:

TokenElevationTypeDefault – User is not using a “split” token. This value indicates that either UAC is disabled, or the process is started by a standard user (not a member of the Administrators group).

The following two values can be returned only if both the UAC is enabled and the user is a member of the Administrator’s group (that is, the user has a “split” token):

TokenElevationTypeFull – the process is running elevated.

TokenElevationTypeLimited – the process is not running elevated.

Return Values:

If the function succeeds, the return value is S_OK. If the function fails, the return value is E_FAIL. To get extended error information, call GetLastError().

HRESULT
IsElevated( __out_opt BOOL * pbElevated = NULL );

Use IsElevated() to determine whether the current process is elevated or not.

Parameters:

pbElevated – [out] [optional] Pointer to a BOOL variable that, if non-NULL, receives the result.

The possible values are:

TRUE – the current process is elevated. This value indicates that either UAC is enabled, and the process was elevated by the administrator, or that UAC is disabled and the process was started by a user who is a member of the Administrators group.

FALSE – the current process is not elevated (limited). This value indicates that either UAC is enabled, and the process was started normally, without the elevation, or that UAC is disabled and the process was started by a standard user.

Return Values

If the function succeeds, and the current process is elevated, the return value is S_OK. If the function succeeds, and the current process is not elevated, the return value is S_FALSE. If the function fails, the return value is E_FAIL. To get extended error information, call GetLastError().

BOOL
RunElevated(
__in HWND hwnd,
__in LPCTSTR pszPath,
__in_opt LPCTSTR pszParameters = NULL,
__in_opt LPCTSTR pszDirectory = NULL );

Use RunElevated() to start an elevated process. This function calls ShellExecEx() with the verb “runas” to start the elevated process.

Parameters:

hwnd – [in] Window handle to any message boxes that the system might produce while executing this function.

pszPath -[in] Address of a null-terminated string that specifies the name of the executable file that should be used to start the process.

pszParameters – [in] [optional] Address of a null-terminated string that contains the command-line parameters for the process. If NULL, no parameters are passed to the process.

pszDirectory – [in] [optional] Address of a null-terminated string that specifies the name of the working directory. If NULL, the current directory is used as the working directory.

Return Values

If the function succeeds, the return value is TRUE. If the function fails, the return value is FALSE. To get extended error information, call GetLastError().

NOTE: This function will start a process elevated no matter which attribute (asInvoker, highestAvailable, or requireAdministrator) is specified in its manifest, and even if there is no such attribute at all.

BOOL
RunNonElevated(
__in HWND hwnd,
__in LPCTSTR pszPath,
__in_opt LPCTSTR pszParameters = NULL,
__in_opt LPCTSTR pszDirectory = NULL );

Use RunNonElevated() to start a non-elevated process. If the current process is not elevated, it calls ShellExecuteEx() to start the new process. If the current process is elevated, it injects itself into the (non-elevated) shell process, and starts a non-elevated process from there.

Parameters:

hwnd – [in] Window handle to any message boxes that the system might produce while executing this function.

pszPath – [in] Address of a null-terminated string that specifies the executable file that should be used to start the process.

pszParameters – [in] [optional] Address of a null-terminated string that contains the command-line parameters for the process. If NULL, no parameters are passed to the process.

pszDirectory – [in] [optional] Address of a null-terminated string that specifies the name of the working directory. If NULL, the current directory is used as the working directory.

Return Values

If the function succeeds, the return value is TRUE. If the function fails, the return value is FALSE. To get extended error information, call GetLastError().

NOTE: For this function to work, the application must be marked with the asInvoker or highestAvailable attributes in its manifest. If the executable to be started is marked as requireAdministrator, it will be started elevated!

How to use the file VistaTools.cxx

Make sure you have the latest Windows SDK (see msdn.microsoft.com for more information) or this file may not compile!

This file contains the Win32 stuff only, it can be used with or without other frameworks, such as MFC, ATL, etc.

This is a “combo” file that contains both the declarations (usually placed in the .h files) as well as the definitions (usually placed in the .cpp files) of the functions. To get the declarations only, include it as you would any .h file. To get both the declarations and definitions, define IMPLEMENT_VISTA_TOOLS before including the file. (The latter should be done once and only once per project).

For example, to use this file in a MFC project, create a file MyVistaTools.cpp that contains the following:

#include “StdAfx.h”

#define IMPLEMENT_VISTA_TOOLS
#include “VistaTools.cxx”

This would make MyVistaTools.cpp the implementation file of the VistaTools function for your project. Don’t forget to add MyVistaTools.cpp to your project! You can add VistaTools.cxx to your project, as well, but it should be excluded from the build, because its contents is compiled when it is included in MyVistaTools.cpp file with IMPLEMENT_VISTA_TOOLS defined, as shown above.

In other files of your project, where you need to use the functions declared in VistaTools.cxx, include it without defining IMPLEMENT_VISTA_TOOLS, just as you would include a .h file:

#include “VistaTools.cxx”

To use the function RunNonElevated(), this file must be compiled into a DLL. In such a case, define DLL_EXPORTS when compiling the DLL, and do not define DLL_EXPORTS when compiling the projects linking to the DLL.

If you don’t need to use RunNonElevated(), then this file may be a part of an EXE project. In such a case, define DONTWANT_RunNonElevated and NO_DLL_IMPORTS to make this file compile properly.

For an example of using VistaTools.cxx in a real project, see VistaElevator 2.0.

How do I download the file VistaTools.cxx?

Simply right-click on the link below and choose the Save target as command (or similar) to save it to your hard drive:

Download VistaTools.cxx

If you use this file in your own project, an acknowledgment will be appreciated, although it’s not required.

Enjoy!

Did you know? Our USB Encryption Software can protect any USB flash drive or any other external drive with a password and strong encryption. Try it free for 30 days! Read more…

The Hunt For Blue Screen

This story began about 15 months ago, in November 2006. That was the time when Microsoft was getting very close to releasing Windows Vista, and it was the time for me to start getting serious about making sure my applications were compatible with it.

At that time I was using two computers for the development and testing, one with two single-core Intel processors, and another one with one single-core AMD x64 processor. Both were set up for development and testing of my programs: I was using the first one to test the 32-bit versions, and the second one to test the 64-bit editions of my programs. Since many people reported that Vista was more hardware hungry than XP, I thought it was a good occasion for me to also get a more powerful computer that would run Vista reasonably well. So I bought a new Core 2 Duo (dual core) processor, a motherboard to support it (P5L-MX from ASUS), a new video card to support the Aero user interface of Vista, put them together in a spare computer case I had, loaded up Vista Release Candidate on it, and started working on porting my applications to Vista.

It all went well for a while, except every couple of days or so my new powerful computer would once of a sudden “blue screen” and reboot.

After it happened a few times, I fired up WinDbg and loaded a few latest minidumps into it. They indicated that the crashes were happening in the FASTFAT.SYS driver, and the common reason for the errors was IRQL_NOT_LESS_OR_EQUAL, a common reason for a crash caused by a sloppily written device driver. It seemed like a bug in the FASTFAT.SYS driver shipped with the pre-release version of Vista. I decided there was not much I could do but hope that the bug would be fixed in the final (RTM) Vista release.

A couple of months later the RTM release of Vista became available, so I’ve reformatted the hard drive to get rid of the release candidate of Vista, installed a fresh copy of Vista RTM on it, and started using it.

In a day or two the same crashes started to happen again.

Figuring Microsoft would not release a new version of Vista with a buggy version of such an important driver as FASTFAT.SYS, I started looking for another reason. What made it difficult was that the blue screens appeared not very often, sometimes a week would go by and I started to hope I finally found out the reason, but inevitably, it would crash again no matter what I tried. And I tried a plenty:

I vacuumed the inside of the case and reseated the processor and the RAM modules.

The blue screens kept happening.

I ran the memtest program to check the RAM for errors for a few hours, it did not find any problems with the RAM.

The blue screens kept happening.

I installed the SpeedFan program to monitor the temperature of the hardware components. Although it did not show an overheating, I added another fan to the case.

The blue screens kept happening.

I’ve replaced the video card with another one.

The blue screens kept happening.

I’ve bought a new SATA hard drive (previously I was using an old IDE drive), and moved the Vista installation to it.

The blue screens kept happening.

I thought that maybe I got a faulty motherboard, so I bought a new one, this time P5LD2, again from ASUS. I also picked up another Core 2 Duo processor and a new set of RAM modules to go with it. I reinstalled Vista RTM from scratch, and set up my development environment, and started working as usual.

The blue screens kept happening.

As you can see, at that point I already had two computers which were giving me the blue screens every couple of days or so. I ran out of the new theories about the reason for the crashes, and I returned to the one I started with: the bug was probably in the FASTFAT driver of Vista after all, maybe I should have waited till Vista SP1 was out before switching to Vista as my main development platform. I started thinking about switching back to Windows XP. It so happened that at that time (in September 2007) I was locked out of both of my Vista computers by the buggy Genuine Advantage code of Windows Vista (I plan to share that experience of mine in a separate post, later on, stay tuned). That made the decision to switch back to XP real easy.

I was using Windows XP for several years, and never had a problem like that before, so imagine my surprise that after I’ve reinstalled Windows XP on each of my new computers, the blue screens started to happen almost from the day one. As before, they were occurring in the FASTFAT.SYS driver. It made it clear for me that I was blaming Vista in vain, it did not introduce a new bug, or, at least, if the bug was there, it was not Vista-specific.

I started analyzing the similarities between the two new computers, hoping that would give me a clue. They had different motherboards (although from the same manufacturer), slightly different processors, different RAM modules, different video cards, different hard drives (one was using a WD SATA drive, another one a Maxtor IDE drive). I came up with the idea that maybe I got very unlucky and I got two faulty motherboards. Luckily, at that time the built-in network adapter on one of the motherboards died, and I took this opportunity to RMA the motherboard back to ASUS. I got the replacement back in a few days, and installed it.

The blue screens kept happening.

Thinking that getting three faulty motherboards in a row was very unlikely, I started to try other things. Even though my two old computers were plugged in the same UPS device as the new ones and were working just fine, I thought maybe the new computers were more sensitive to the quality of the power they were getting.

I replaced a cheapo generic power supply in one of the new computers with a considerably more expensive and supposedly better one from Antec.

The blue screens kept happening.

I bought a new, more powerful UPS, specifically for use by the new computers.

The blue screens kept happening.

Out of desperation, I started all over and repeated every troubleshooting step I did before, with each of the crashing systems: reseated the modules, replaced the cables, ran the memtest.

The blue screens kept happening.

At that point, about a month ago, I ran out of ideas. I was ready to surrender and just live with it. Or maybe throw out both of the new computers I’ve built and buy a completely new one, and I was seriously contemplating that, when on January 15 it hit me: what that FASTFAT.SYS driver was doing there anyway? All of my hard drives have been formatted with the NTFS file system, I didn’t remember formatting a drive with the FAT or FAT32 system recently. Why would Windows load the FASTFAT driver?

I reviewed the properties of the drives listed in My Computer, and sure enough, there was one of them formatted with the FAT32 system. It was a virtual encrypted drive I created a while back with the TrueCrypt software. I used the drive as a backup place for sensitive files of mine. Periodically, I would burn the image to a DVD-R disc, to make a backup of it. And yes, there was a copy of this image on each of the new computers experiencing the crashes.

I reformatted the encrypted volumes with the NTFS file system.

The blue screens stopped.

It’s been almost a month since I’ve made the last change, and I have not had a single blue screen. Previously, they were happening every couple of days. I’m very confident now that I’ve found the culprit that caused me so much grief. I believe the following list describes the common conditions for the blue screens to occur:

  1. The computer should have a multi-core processor, such as Intel Core 2 Duo.
  2. The computer should have TrueCrypt 4.3a installed, and there should be an encrypted FAT32 volume mounted.

Why do I think the first condition is important? Because previously I was using TrueCrypt with FAT32 virtual drives for several years on the computers that had single-core processors, and never experienced such crashes with them. Only when I switched to the Core 2 Duo processors the crashes started to occur.

I’ve looked through the source code of TrueCrypt 4.3a and noticed that its driver was compiled with the NT_UP switch in its Makefile. This is definitely wrong. It means that the driver was targeted at the uni-processor systems. Since the multi-core processors are essentially multi-processors, defining NT_UP means asking for trouble.

Why did the crashes stopped after I’ve reformatted the encrypted drives with the NTFS file system? I don’t know. Apparently the NTFS file system driver is more robust and can tolerate the imperfect drivers such as the ones compiled with the NT_UP switch. Why didn’t I get crashes with my old two-processor computer? Again, I don’t know. Maybe the old computer was not fast enough for the error conditions to occur so frequently, and when it did crash once in a blue moon, I just dismissed that as something insignificant and did not pay attention to it.

Now, I noticed that a few days ago a new version of TrueCrypt 5.0 had been released. It uses a new driver build procedure, that does not seem to have the NT_UP flag anymore. This is good. However, looking through their support forums it seems like the new version introduced quite a few new bugs. I guess I’ll postpone upgrading to it until version 5.1 comes out. I want to get some rest from the blue screens for awhile :-)

Update: April 15, 2008

A few days ago I decided to try the latest release of TrueCrypt, 5.1a. I reformatted the NTFS encrypted volume back to FAT32 and the blue screens started to occur almost immediately. After two days of bluescreening, I reformatted the volume back to NTFS, and the blue screens stopped. It looks like TrueCrypt 5.1a still causes this problem. HTH.

Update: May 13, 2008

A week ago I started another experiment : connected a spare hard drive about the same size as the TrueCrypt volume I use, formatted the hard drive with the FAT32 system (just like the TrueCrypt volume that was giving me the blue screens), and copied everything from the encrypted volume to that hard drive. Then I dismounted the TrueCrypt volume, and assigned its drive letter to the hard drive I’ve just attached. Restarted the computer and kept using it as before, the only difference was that instead of a FAT32-formatted encrypted volume I was now using a regular FAT32-formatted unencrypted hard drive. A week passed by, no blue screens. Today I copied everything back from the hard drive to the FAT32-formatted TrueCrypt volume, and disconnected the extra hard drive. About an hour later a blue screen occurred. I think that proves conclusively that TrueCrypt is the real culprit behind these blue screens. HTH.

Update: July 16, 2008.

A week ago I’ve installed a new version 6.0a of TrueCrypt. One of the new things in it was an updated device driver with the improved support for the multi-core processors. That gave me the hope that this version might have finally fixed this bug. For a week it was running  smooth, no BSoDs, even though I’ve switched to using a FAT-formatted encrypted volume. I was thinking about reporting success here, but today – boom, blue screen with IRQL_NOT_LESS_OR_EQUAL status in fastfat.sys.  So I’m switching back to the NTFS volume and reporting for now that version 6.0a of TrueCrypt still has not fixed this problem. HTH.

Did you know? Our USB Encryption Software can protect any USB flash drive or any other external drive with a password and strong encryption. Try it free for 30 days! Read more…

A handy macro for Visual C++ developers: BuildStartupProject

I can’t believe I did not know this before: it’s possible to set up Visual Studio to use F7 to build the startup project rather than the selected one!

As a matter of fact, that was the default behavior of the F7 key in Visual Studio 6.0, but then in Visual Studio .NET 2003 (or maybe even in 2002?) Microsoft decided to change it to build the selected project rather than the startup one. This change made the build process somewhat inconvenient: if I happened to work with a file that belonged to a DLL and pressed F7, that would build that particular DLL only, while I wanted to build the whole thing – the executable that links to the DLL. In order to do that, I would need to select the EXE project first, then press the F7 key. I don’t know how many microseconds I’ve wasted doing that.

I could have changed the behavior of the F7 key by binding it to the Build.BuildStartupProject command, but the problem was, Visual Studio did not have such a command! The only choices available were: BuildSelection, BuildSolution, and similar, but there was no command to build the startup project. That’s one more thing I cannot believe, that Microsoft has not added such a command for such a long time: it’s still not present in Visual Studio 2008, the latest version as of this writing.

Today, for some reason I got very annoyed by my inability to use the F7 key the way I wanted, so I decided to search for a solution on the Internet, and (miracle!) I’ve found it. I’ll kick myself for a long time for not trying to find it before.

Anyway, the solution is a simple three-line macro I found in the BorisJ’s blog:

Sub BuildStartupProject()

    Dim sb As SolutionBuild = DTE.Solution.SolutionBuild

    Dim projName As String = sb.StartupProjects(0)

    sb.BuildProject(sb.ActiveConfiguration.Name, projName, False)

End Sub

As soon as I added it to my custom macros list in Visual Studio, and assigned F7 to run that macro, I could build the current startup project no matter what file I was working with.

One problem I had with the macro was that it did not bring the output window to the foreground when starting the build process, so I added a line that does that.

Another problem was that when I wanted to build for a different platform (such as x64), the macro still compiled for Win32. So I fixed it a bit to make it compile for the correct platform.

Here is the resultant macro :

Sub BuildStartupProject()

    DTE.ExecuteCommand("View.Output")

    Dim sb As SolutionBuild = DTE.Solution.SolutionBuild

    Dim projName As String = sb.StartupProjects(0)

    sb.BuildProject(sb.ActiveConfiguration.Name + "|" + _
                    sb.ActiveConfiguration.PlatformName, projName, False)

End Sub

Hope this helps someone. Did I mention I can’t believe I have not found this solution long ago? :-)

Did you know? Our USB Encryption Software can protect any USB flash drive or any other external drive with a password and strong encryption. Try it free for 30 days! Read more…

WinUnit and Structured Exception Handling (SEH)

Recently I was working on a native C/C++ library, and I was searching for a good unit testing framework to use with it. I took a look at TUT, CppUnit, and a couple of others, and was trying to decide which one to choose, when a new issue (February 2008) of the MSDN Magazine arrived. Turned out it came just in time because of the little gem it contained: an article by Maria Blees describing WinUnit, a unit testing framework she developed.

I downloaded the code, compiled the WinUnit.exe program from it, gave it a try, and immediately liked what I saw. Most of all I was impressed by how easy it was to get started: all I needed to do was create an empty DLL project, specify WinUnit.exe in its command line for the debugging, and presto, I was ready to add unit tests to my library!

Of course, designing the unit tests themselves was not that easy, but WinUnit made the process painless and even fun (if unit tests can be fun at all :-) ) Let me give a small example: suppose that for some reason you want to have your own version of the strlen() function, let’s call it MyStrLen(). It should accept a pointer to a TCHAR string and return the number of characters it contains:

size_t 
MyStrLen( LPCTSTR psz ) 
{ 
    size_t nLen = 0;           

    if ( psz == NULL ) 
        throw _T("Null pointer!"); 

    while( *psz++ ) 
         nLen++;            

    return nLen; 
}

How would you test this function with WinUnit? Here is how I would do it:

#include <WinUnit.h> 
#include "MyStrLen.h"           

BEGIN_TEST( MyStrLen_ShouldReturnZeroForEmptyString ) 
{ 
    WIN_ASSERT_ZERO( MyStrLen( _T("") ) ); 
} 
END_TEST           

BEGIN_TEST( MyStrLen_ShouldReturnCorrectLengthForNotEmptyStrings ) 
{ 
    WIN_ASSERT_EQUAL( 1, MyStrLen( _T("a") ) ); 
    WIN_ASSERT_EQUAL( 2, MyStrLen( _T("ab") ) ); 
    WIN_ASSERT_EQUAL( 26, MyStrLen( _T("abcdefghijklmnopqrstuvwxyz") ) ); 
} 
END_TEST           

BEGIN_TEST( MyStrLen_ShouldThrowForNullPointer ) 
{ 
    WIN_ASSERT_THROWS( MyStrLen( NULL ), LPCTSTR ); 
} 
END_TEST

Pretty self-explanatory, isn’t it? Each test gets a name, starts with the macro BEGIN_TEST, and ends with the macro END_TEST. The tests call the function being tested and verify the results using various WIN_ASSERT… macros provided by WinUnit. For the more complex tests one can also use the “fixtures”, and the macros that go with them: FIXTURE, SETUP, TEARDOWN, BEGIN_TESTF, and END_TESTF. See the article for the details.

To run the tests, you just press the F5 key in Visual Studio IDE, and WinUnit.exe loads your test DLL, executes all the tests it finds in it, and sends the output directly to the output window of Visual Studio. If a test does not check, you can double click on the “failed” message in the output window and it takes you right to the line that failed the verification, letting you see what’s going on. In short, it works just the way I would expect it to work.

One problem I encountered was when trying to write tests for functions that were using the Structured Exception Handling (SEH) mechanism instead of the C++ exceptions. (Why did I need that? Because the library I’ve been writing contains quite a few of pure C code (not C++), and you cannot use C++ exceptions in the C files). When trying to compile tests for such C files, the compiler complained that it couldn’t mix the SEH and C++ exceptions in the same function. Having looked into the WinUnit.h file, I’ve come up with the following macros that can be used instead of the usual ones:

BEGIN_TEST_SEH( TestName ) 
END_TEST_SEH 
FIXTURE_SEH( FixtureName ) 
SETUP_SEH( FixtureName ) 
TEARDOWN_SEH( FixtureName ) 
BEGIN_TESTF_SEH( TestName, FixtureName ) 
END_TESTF_SEH( FixtureName ) 
WIN_ASSERT_THROWS_SEH( expression, ... )

(I’ve put them in a separate file, WinUnitSEH.h).

Now, if the MyStrLen() function were throwing a SEH exception, for example by calling the RaiseException() function instead of using the throw operator, the last test could be rewritten as follows:

#include <WinUnitSEH.h>          

BEGIN_TEST_SEH( MyStrLen_ShouldThrowForNullPointerSEH ) 
{ 
    WIN_ASSERT_THROWS_SEH( MyStrLen( NULL ) ); 
} 
END_TEST_SEH

Hope this helps someone. Download WinUnitSEH.h

Virtually everything

Being in the software business, I have to upgrade my main development machine rather often. When switching to a new computer, the most frustrating part of the process is setting it up just the way I like it. That means not only moving the source code and other files over, but also installing the applications I need, configuring their settings, fine-tuning their options to make they work just right. I used to spend at least a couple of days doing such tedious tasks, before I could start to actually work with the new computer.

A couple of years ago, when preparing to move to a yet another new computer, and remembering how depressing it was the previous time, I decided to try something new: instead of reinstalling all my development tools directly, I created a virtual machine in the new computer first, and then installed the applications and utilities inside of that virtual computer. From that time on, I work from within the virtual machine, using the real computer just as the host of the virtual one.

Now, a couple of years later, I can say that that was one of the best moves I’ve done that reduced my stress level and increased my productivity. I had to move to a new computer a couple of times after that, and when I did that, all I needed to do to recreate my familiar development environment was to install the virtual machine software, copy the virtual machine to the new computer, and presto – I was back in the game in no time at all. Another convenience was that whenever I went on a trip, all I needed to do to take my development shop with me was copy the virtual machine to the laptop, and I could keep working on my software projects while on the go!

Of course, going virtual for software development requires the host computer to have a fast processor and plenty of RAM (a fast hard drive does not hurt, too). My current host computer has 2 GB of RAM and uses a Core 2 Duo processor that provides hardware support for virtualization. That makes my software development application (Microsoft Visual Studio) to work within the virtual machine just as fast as within the real one. (At least that’s how it feels, I did not do any special timings).

I liked having an independent virtual machine for the software development so much that a bit later I’ve created a few more dedicated virtual machines to run other parts of my software business as well: one such machine contains all my web site development tools and applications, including a local web server running the local copy of my web sites. Another virtual machine is dedicated to keeping the database of the customers, bookkeeping software, and other related tools.

In case you’ve spent the last few years on the moon and are not familiar with the virtual machine software, you can get started by taking a look at Microsoft Virtual PC and/or VMWare Server: both are easy to set up and use, both are free, both have good performance. VMWare Server offers more flexibility in the virtual machine configuration, and it provides support for the USB devices, while Virtual PC is easier to setup and use. I use both Virtual PC and VMWare Server, but I could not get them both to work on the same computer at the same time: if one of them was running, then an attempt to start the other one caused the host computer to crash. However, using them one at a time or on different host computers caused no problems.

One drawback of setting up the virtual machines is that many software vendors treat them like separate physical computers, and if you have purchased a one-computer license, you may not be allowed to install separate copies of the software in several virtual machines, even if they operate on the same physical host computer. I find such restrictions quite annoying. (They are the relicts from the old pre-virtual computing days). If you have a software tool that you must install in more than one virtual machine, check its license agreement, and if you find that you are not allowed to use the software in several virtual machines, contact the vendor and ask them to reconsider their license terms. If enough of us start demanding it, they may actually do that.

My New Year resolution for 2008

… is: to start this blog!

Yes, I know, I’m late to this blogging game by at least a couple of years, but better later than never, right?

What finally convinced me to give blogging a try were two books I’ve read recently: “The Corporate Blogging Book” by Debbie Weil, and “Clear Blogging” by Bob Walsh. These books contain a lot of good advice (which I’m hoping to put to good use here). If you don’t have a blog yet, but are thinking about starting one, I highly recommend these two books.

My plans for this blog are modest for now: I’m going to write about once or twice every week or so, on the topics I’m most familiar with: computers, software, running a small business. Of course, I’m going to slip through photos of my cats once in a while, as well :-)

Meanwhile, happy New 2008 Year everybody, let it bring you new happiness, joy, wealth, health, and everything else you wish for yourself!