Mac Market Share Increasing!

I was at the local library today to do a couple hours programming in a quiet environment without the normal distractions of my home office. To my surprise when I looked around I saw a sea of Apple MacBook and MacBook Pro laptops. Sure, there were a few Toshiba or HP laptops too, but the majority of the machines in the room had shinning bright Apple logos on the screens.

My unscientific survey in the library today yielded the following numbers:

System Count
White MacBook 2
Unibody 13″ Macbook 1
15″ MacBook Pro 2
12″ PowerBook 1
Toshiba 1
HP 2

That breaks down to 60% Apple, 40% Microsoft.

Now that’s what I like to see! Maybe the recent discussion on the macsb about Mac market share isn’t so far fetched after all. Here are a few interesting links:

Who knows if this is all true or not. With the recent announcement that Steve Jobs will be taking a six month leave of absense from Apple due to health concerns the future for Apple is less clear than it once was. I’m sure Apple will do just fine over the next 12-18 months since there are a number of products already in development. The big concern has to be about the sort of innovations that Apple can concieve of and execute on after the current pipeline runs dry. Will there be other folks at Apple with the same vision and forsight as Steve Jobs? Probably, but it is far from certain.

Atleast for now it seems like the market share for Apple will continue to climb. Microsoft will have to hit a home run with the new Windows 7 operating system if they want to fend off the onslaught of Mac OS X. Being a long time developer on both platforms I can say that from my point of view having more users on the Mac makes me happy! I look forward to developing, releasing and selling more applications on the Mac platform.

You can’t keep a good class library down … MFC gets reprieve from death sentence!

A few years ago I was working at a company where we built applications using Visual Studio 6 and MFC. The applications had been around for about 10-12 years, and were all showing their age. Customers were beginning to request updated user interface features like they were seeing in modern Microsoft products such as Office and Internet Explorer. Sadly, we could not deliver these user interface enhancements easily because MFC was not getting any attention from Microsoft.

In late 2002 Microsoft was pushing the .NET Framework, C# and WinForms as the heir apparent for Win32, C++ and MFC. Converting a decade of legacy C++ MFC code to .NET and WinForms just wasn’t an option. We all felt like Microsoft had just abandoned us for greener pastures.

Our solution at the time was to start a long difficult process of moving away from MFC toward a cross-platform class library built by Trolltech, called Qt. In many respects this turned out to be a good decision since it meant we could begin to seriously consider offering our applications on Windows, Linux and the Mac instead of just on Windows. Still, it felt like Microsoft had hung us out to dry.

The WinForms classes just were not rich enough to build complex desktop applications at the time. Many of the conveniences we had come to rely upon from the MFC class libraries were missing and it would have been up to us to roll our own alternatives had we gone down the WinForms route. I think Microsoft was too focused on building web applications to devote sufficient resources to WinForms.

Here we are six years later and Microsoft has announced that they are providing a MFC Feature Pack for Visual C++ 2008 that will add significantly to the capabilities of the MFC class libraries. I can hear MFC development teams all across the Internet celebrating this change in stance from Microsoft.

Here are a couple links to information from Microsoft on the topic:

Couple MFC with a good third-party widget library like the toolkit offered by CodeJock Software and you have everything necessary to build some awesome new desktop applications.

Long Live MFC!

Microsoft Professional Developers Conference 2008 – See you there?


The last time I attended the Microsoft Professional Developer Conference was back in 2001, shortly after the attacks of September 11th, 2001. Just over 6000 people made the trip to Los Angeles to learn about the latest technologies from Microsoft, as they were in the midst of rolling out the .NET Framework. They were pushing Hailstorm (I still have the free book they gave everyone with the Hailstorm API in it. I never did get a chance to use it though.). Everyone was excited about building new web services using .NET and C#.

A lot has changed since then. Vista and Windows Server 2008 are here, the .NET Framework has gone through three major revisions, Visual Studio has seen major improvements supporting team development, Intel has delivered multi-core processors and Microsoft still hasn’t delivered on the promise that was Hailstorm.

The preliminary agenda for PDC 2008 has some interesting sessions listed. Topics I am hoping to learn more about this year include:

  • Silverlight
  • Visual Studio 10
  • Windows 7
  • Multi-core Programming Techniques

Even though Bill Gates is now officially retired it looks like he is scheduled to speak at the conference as well. For a geeky college dropout with a whiny voice he does a great job delivering keynotes to developers. He doesn’t have the stage presence of a Steve Jobs, but he isn’t running Apple either. I look forward to hearing what his message for Microsoft developers is this year.

The dates for the conference are October 26 – 30, and the event is being held at the Los Angeles Convention Center once again. I hope to see you there.

How to enable MSI Logging

If you are trying to debug an installer problem it is probably worth having MSI logging turned on. This will produce a file in your %TEMP% directory that contains a detailed trace of the activities that took place in MSIEXEC. This can be very helpful when an install or uninstall fails without any clear indication as to why it failed.

Log files are stored in the directory pointed to by the TEMP environment variable. The filename format is MSIxxxx.LOG, where xxxx is replaced with a random string. A new log file is created for each invocation of MSIEXEC.

To enable logging through group policy, do the following:

  • Start / Run… / gpedit.msc
  • Drill down into Local Computer Policy / Computer Configuration / Administrative Templates / Windows Components / Windows Installer / Logging
  • Enable logging with the setting “voicewarmup”. These are the command-line arguments that MSIEXEC will use.

These links contain more information on setting up logging:

GetQueuedCompletionStatus() – Devil in the Details!

One of the projects I work on makes use of the Win32 asynchronous I/O model for managing network traffic between a Windows Service and a custom-built network device.

One of the key Win32 APIs we use is called GetQueuedCompletionStatus. This API provides access to an I/O completion port that is managed by a separate operating system thread.

When dealing with this API and Windows asynchronous I/O in general it helps to think about the model as being supported by a separate workpool thread. This API gives the caller a way to synchronize with the operations of that workpool thread (or threads).

The prototype for this API is as follows:

BOOL GetQueuedCompletionStatus(
	HANDLE CompletionPort, 
	LPDWORD lpNumberofBytes, 
	PULONG_PTR lpCompletionKey, 
	LPOVERLAPED* lpOverlapped, 
	DWORD dwMilliseconds);

At first glance the API may not seem too complex. There are 5 parameters and a boolean return type. Some of the parameters are easy to figure out just be looking at their names. Others are less clear. You could speculate that the returned boolean is an indicator of whether or not the operation was successful or not. It is easy to be lulled into a false sense of understanding by reading through the first few paragraphs of the MSDN documentation on this API.

It actually turns out that this API is very complex (perhaps too complex?), and careful study of the MSDN documentation is required if you wish to handle all of the possible conditions when this API returns. Pay careful attention to the section in the documentation that discusses Return Values and Remarks.

My favorite gem from the return values section (and the one I recently missed when using this API) is:

If a socket handle associated with a completion port is closed, GetQueuedCompletionStatus returns ERROR_SUCCESS, with *lpOverlaped non-NULL and lpNumberOfBytes equal to zero.

In other words, when the socket is closed (possibly because the peer closed it) you will get what appears to be a successful I/O completion. This does not represent what most would consider a successful return, and if you have not carefully checked the other parameters, your code may mis-interpret this condition.

Another area where you need to be careful when using Windows Asynchronous I/O is application shutdown. There may be a number of pending I/O operations that have been queued to the I/O completion port. It is your responsibility to finish processing all of these I/O operations (possibly by first closing the socket and then handling each failed I/O completion event) and release any resources that were allocated for the I/O operations. Failing to do this will likely result in a memory leak for the application.

The moral of the story is to always read the entire MSDN documentation page and make sure your code handles all of the possible combinations of return values!

WinQual Registration Head Aches

In order to digitally sign Windows drivers you need what Microsoft called an Authenticode Digital Certificate. The company I work is creating a number of drivers, so we had a need for an Authenticode Digital Certificate. The certificate would also be used to sign the Microsoft installer packages that we release to customers.

Being a cost conscious group we shopped around and identified two main sources for Authenticode digital certificates.

* VeriSign
* Thawte

Comparing the prices it seemed clear that the Thawte certificate was a better bet so that is what we purchased. Everything appeared to be fine until we tried to join the WinQual program. That is when I started asking myself the following question:

Question: When is an Authenticode Digital Certificate not an Authenticode Digital Certificate?

Answer: When you try and use it in the application process for joining the WinQual program.

In the last couple weeks I have been learning about the requirements to digitally sign Windows device drivers. My strategy has been to take the Toaster sample from Microsoft and try to duplicate all of the steps necessary to build a signed version of the driver. Naively, I figured it should be easy to replicate the steps taken by Microsoft to sign this sample program. Boy was I wrong!

It turns out that there is a utility called inf2cat or something like that. Microsoft recommends using it to create the category file containing hashes of the files you want digitally signed as part of your driver package. So, for me to replicate the Toaster sample signing process I need a copy of inf2cat. This tool is apparently only available to members of the WinQual program that Microsoft runs.

Okay, so I need to join WinQual. How hard could that be. I went to and learned that in order to joint he program you must submit a file to them that is digitally signed with your Authenticode certificate. So off I went to get an Authenticode certificate for my company. After a few google searches I came to the conclusion that VeriSign and Thawte are the two primary sources for these certificates, and Thawte is considerably cheaper. I purchased an Authenticode certificate from Thawte and a few days later the certificate was on my machine and it was time to make the membership request on the WinQual site.

I followed all of the instructions to digitally sign the required file using my new Authenticode certificate. Everything seemed to go smoothly until I tried to upload the signed file to Microsoft. Their web site kept saying that the file was not signed correctly. I went back to the main WinQual web page to try and find an answer to this problem. There was nothing there to help me solve this mystery so I went to the only other resource I could think of. That is the DDK mailing list archives at OSR. These folks have been doing Windows driver work for ages and if anyone knew what was wrong, I was sure the answers would be on their mailing list.

It only took one keyword search of the archives to learn what the problem was. It seems that not all Authenticode digital certificates are created equal, and Microsoft has a predilection to those minted by VeriSign. My new Thawte digital certificate would be just fine for signing my drivers, but it would not be at all useful in joining the WinQual program. It was beginning to look like I needed to buy another Authenticode certificate from VeriSign in order to join the WinQual program.

After carefully re-reading the WinQual page describing the ways to join the program I learned that you could also sign your membership request using something called a Corporate Identifier. It was a cheaper, less capable digital certificate that could be used to sign the file and join the program. This certificate could be purchased from VeriSign for $99.

I waited another couple days and the new Corporate Identifier finally appeared in my inbox. I followed the instructions to sign the file, upload it, and this time I met with success in joining the WinQual program.

So, instead of saving money by using the Thawte certificate I ended up spending roughly the same amount of money that it would have cost to just purchase the Authenticode certificate from VeriSign. The difference was that because the WinQual site was not clear on the specific requirements for using a VeriSign certificate I ended up wasting at least 2 or 3 days trying to join the WinQual program.

In the end it was clear that I should have purchased the “name brand” digital certificate from VeriSign.

HOWTO – Use Visual Studio 2005 for Qt Open Source Development


Trolltech has released Qt 4 under a dual-license for all supported platforms. In earlier versions of Qt they only released the open source version for Mac and Linux, leaving Windows developers with no choice but to purchase a commercial license. That all changed with the release of Qt 4 when Trolltech started to provide an open source version for Windows development too! The only catch was that Trolltech only supports the MinGW GCC compiler for development using the open source version.

This article describes how to patch Qt 4 open source edition on Windows so you can develop using Visual Studio 2005. You can even develop using the free Express edition of Visual Studio 2005 so long as you also install the latest Platform SDK.

Please keep in mind that these patches and tips are not provided so you can get around the very generous Trolltech dual-license terms of use. If you are developing or intend to develop a commercial application using Qt 4 you must purchase a commercial license for Qt 4. Only use the information provided in this article if you wish to develop open source GPL software for the Windows platform and wish to use the Microsoft Visual C++ 2005 compiler instead of the MinGW GCC compiler.

Download Qt 4.1 Source Code, Patches, and Notes

Building Qt 4.1 using Visual C++ 2005

Open C:\qt-win-opensource-src-4.1.0 in Windows Explorer.
Double-click on the “Qt 4.1 Command Prompt” shortcut to open a Command Prompt window with the environment setup for Qt 4.1 development. IMPORTANT: You must already have Visual Studio 2005 installed. You may need to edit setenv.cmd if your copy of Visual Studio 2005 is not in the default location.

Run “installpatch41.bat”
This will patch the Qt 4.1 source code so it builds properly using the Visual C++ 2005 compiler.

Run “build.cmd”
This will build all of the Qt 4.1 libraries, utilities, and sample applications using the Visual C++ 2005 compiler.

To rebuild, if necessary, make sure to first clean up the previous build. Do this by running
nmake distclean

from the C:\qt-win-opensource-src-4.1.0 directory.

External Tools Configuration in Visual Studio 2005

Launch Visual Studio 2005 and select the “External Tools…” item from the Tools menu.
Use the “Add button to define each of the following external tools:

Title ……………….. QMake (Project File Generation Mode)
Command ……………… D:\qt-win-opensource-src-4.1.0\bin\qmake.exe
Arguments ……………. -project -spec win32-msvc2005
Initial directory …….. $(ProjectDir)
Use Output window …….. [X]
Treat output as Unicode .. [ ]
Prompt for arguments ….. [ ]
Close on exit ………… [X]

Title ……………….. QMake (Makefile Generation Mode)
Command ……………… D:\qt-win-opensource-src-4.1.0\bin\qmake.exe
Arguments ……………. -makefile -spec win32-msvc2005
Initial directory …….. $(ProjectDir)
Use Output window …….. [X]
Treat output as Unicode .. [ ]
Prompt for arguments ….. [ ]
Close on exit ………… [X]

Title ……………….. Qt Designer
Command ……………… D:\qt-win-opensource-src-4.1.0\bin\designer.exe
Arguments …………….
Initial directory …….. $(ProjectDir)
Use Output window …….. [ ]
Treat output as Unicode .. [ ]
Prompt for arguments ….. [ ]
Close on exit ………… [ ]

Title ……………….. Qt Assistant
Command ……………… D:\qt-win-opensource-src-4.1.0\bin\assistant.exe
Arguments …………….
Initial directory …….. $(ProjectDir)
Use Output window …….. [ ]
Treat output as Unicode .. [ ]
Prompt for arguments ….. [ ]
Close on exit ………… [ ]
Adding a Qt 4.1 Development Toolbar

Add a new toolbar for Qt 4.1 Development by selecting “Customize…” from the Tools menu. Once the “Customize” dialog appears select the “Toolbars” tab and press “New…” For the toolbar name enter “Qt 4.1 Development” and press “OK”.
Select the “Commands” tab on the “Customize” dialog. Select “Tools” from the “Categories:” list. Scroll down in the “Commands:” list until you see “External Command 7”. Drag commands 7, 8, 9, and 10 onto the new “Qt 4.1 Development” toolbar.
Creating a New Visual Studio 2005 Project

Open the “New Project” dialog by selecting File->New->Project… from the menu. Under “Project types” on the left side of the dialog expand “Visual C++” and then select “General.” The right side of the dialog will display a list of all the general project types. Select “Makefile Project” from the list of project types. Provide a name for the project and set the location on disk where you wish the project to be saved. Be sure not to check “Create directory for solution”, as this will create an extra level of directories that is just confusing. Click the “OK” button and you will be presented with the “Makefile Application Wizard.” Simply press the “Finish” button on the first page of the wizard.

Once the project has been created and opened, set the NMake Configuration Properties for the project as shown below. In the “Solution Explorer” right-click on the name of your project. Select “Properties…” from the context menu. On the property pages dialog select “Configuration Properties” and “NMake” on the left side tree control. On the right side, enter the following information, making sure to set the properties for both the debug and release configurations.

Release Configuration Settings

Build Command Line …………………. nmake release-all
Rebuild All Commaond Line …………… nmake release-clean release-all
Clean Command Line …………………. nmake release-clean
Output ……………………………. foo.exe

Common Language Runtime Support ……… No Common Language Runtime support
Include Search Path ………………… “c:/qt-win-opensource-src-4.1.0/include/QtCore”;
Forced Includes …………………….
Assembly Search Path ………………..
Forced Using Assemblies ……………..
Debug Configuration Settings

Build Command Line …………………. nmake debug-all
Rebuild All Commaond Line …………… nmake debug-clean debug-all
Clean Command Line …………………. nmake debug-clean
Output ……………………………. food.exe

Common Language Runtime Support ……… No Common Language Runtime support
Preprocessor Definitions ……………. WIN32;_DEBUG;UNICODE;QT_LARGEFILE_SUPPORT;QT_DLL;
Include Search Path ………………… “c:/qt-win-opensource-src-4.1.0/include/QtCore”;
Forced Includes …………………….
Assembly Search Path ………………..
Forced Using Assemblies ……………..
QMake Project Settings

Create a project file called “” in the directory for your makefile project. Replace the name “” with the name of your actual application. Place the file in the directory where your Visual Studio project was created. To start with, the contents might look something like this:

CONFIG += qt
SOURCES += foo.cpp
HEADERS += foo.h
FORMS += foo.ui
You should be off and running now. For more detailed information I would suggest reading the qmake reference manual. You might also want to take a look at the Qt 4.1 tutorials in Qt Assistant. Have fun!