WIX 3.0 Driver Install Workaround

This article describes a workaround to install a driver using an existing WIX 3.0 based installer. Unfortunately, at the time of this writing the latest WIX 3.0 build does not support driver installations because the DifXApp.wixlib has not been reworked for WIX 3.0. However, WIX 2.0 supports driver installations quite nicely. The workaround is to create a WIX 2.0 merge module that is included in your WIX 3.0 installer.

1. Create a merge module in WIX 2.0 to install the driver like so:


<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns='http://schemas.microsoft.com/wix/2003/01/wi'>
<Module Id='Example' Guid='PUT-GUID-HERE' Language='1033' Version="1.0.0.0">
<Package Id='PUT-GUID-HERE' Description="Driver Merge Module Example"/>

<Directory Id='TARGETDIR' Name='SourceDir'>
 <Directory Id='INSTALLDIR' Name='Drivers'>
  <Component
   Id="Example Driver Component"
   Guid="PUT-GUID-HERE"
   DriverAddRemovePrograms='yes'
   DriverDeleteFiles='no'
   DriverForceInstall='no'
   DriverLegacy='yes'
   DriverPlugAndPlayPrompt='no'
   DriverSequence='0'>

   <File Id='DRIVERINF' Name='driver.inf' LongName='driver.inf' Source='driver.inf' />
  </Component>
 </Directory>
</Directory>

</Module>
</Wix>

2. Include the merge module in your WIX 3.0 project like so:


<Directory Id='TARGETDIR' Name='SourceDir'>
 <Directory Id='INSTALLDIR' Name='MyApplicationInstallDir' />
  <Merge Id='Driver' Language='1033' SourceFile='Driver.msm' DiskId='1' />
 </Directory>
</Directory>

<Feature Id='MainProgram' Title='Program' Description='The main executable.' Level='1'>
 <MergeRef Id='Driver' />
</Feature>

3. Include the following libraries that contain necessary custom actions to install a driver in your WIX 2.0 lib directory: DifXApp.wixlib, DifXApp.dll, and DifXAppA.dll. These files can be found in the latest WDK (Windows Driver Kit).

4. If you are using Visual Studio 2005 it’s possible to include your WIX 2.0 project with you WIX 3.0 solution. First, create a new merge module project in your solution. Second, manually edit the newly created .wixproj file to have the WIX tool chain point to the WIX 2.0 directory.

There you go. Happy driver installations.

Leave a Comment

Singleton Pattern Caveats in Java

The singleton design pattern arguably the simplest pattern to implement. Unfortunately there are some caveats when implementing it in Java. To recap, GoF defines the singleton as follows:

“Ensure a class only has one instance, and provide a global point of access to it.”

A simple Java implementation of the singleton design pattern is:


public class Singleton {
   private static Singleton mInstance;

   private Singleton() {}

   public Singleton getInstance() {
      if (mInstance == null)                // Step 1
         mInstance = new Singleton();  // Step 2

      return mInstance;
   }
}

The main caveat is that the above implementation is not thread safe. Imagine the Singleton instance is not initialized and two threads call getInstance() at the same time:

  1. Thread 1 reaches step 1, checks that mInstance is null and proceeds to step 2.
  2. Thread 1 is preempted by thread 2 before mInstance is instantiated by thread 1.
  3. Thread 2 reaches step 1, checks that mInstance is null and proceeds to step 2.
  4. Thread 2 is preempted by thread 1.
  5. Thread 1 initializes mInstance and returns it.
  6. Thread 1 is preempted by thread 2.
  7. Thread 2 instantiates a new instance of Singleton, assigns it to mInstance and returns it.

Now, there are two instances of the Singleton class which violates the definition of a Singleton: “Ensure a class only has one instance.” The easy solution is to synchronize the getInstance() method:


public class Singleton {
   private static Singleton mInstance;

   private Singleton() {}

   public synchronized Singleton getInstance() {

      if (mInstance == null)                  // Step 1
         mInstance = new Singleton();    // Step 2

      return mInstance;
   }
}

Synchronizing the getInstance() method is not desirable because synchronization is expensive and the getInstance() method only needs to be synchronized the first time it’s called.

My favorite design patterns book, Head First Design Patterns, identifies this problem and suggests the following solution:


public class Singleton {
   private static volatile Singleton mInstance;

   private Singleton() {}

   public Singleton getInstance() {
      if (mInstance == null) {
         synchronized (Singleton.class) {
            if (mInstance == null)
               mInstance = new Singleton();
         }
      }

      return mInstance;
   }
}

The above technique is called “double-checked locking” and ensures that synchronization is only used the first time a singleton is initialized. Note that this technique only works in Java 1.5 and above because the volitile keyword has been fixed: see this article for more details. The article also points out that using the volitile keyword does not provide much of a performance boost over synchronizing the getInstance() method so the following solution is recommended:


public class Singleton {

   private Singleton() {}

   private static class SingletonHolder {
      private static final Singleton INSTANCE = new Singleton();
   }

   public Singleton getInstance() {
      return SingletonHolder.INSTANCE;
   }
}

The above solution is thread safe and offers lazy initialization. It is thread safe because the Singleton instance is initialized when the SingletonHolder class’s static initializer is run. Static initializers are run when the class is initialized. The java language specification guarantees class initialization to be synchronized (see JLS 12.4.2). The solution offers lazy initialization because the SingletonHolder class is not initialized until it is referenced by the getInstance() method (see JLS 12.4.1).

Leave a Comment

Eclipse CVS Attic

Today I was wondering how to get a file out of the CVS attic and back into a project. A quick google search brought up a short article explaining the simple procedure. In Eclipse right click somewhere in the project and select:

Team -> Restore From Repository…

This will bring up the “Restore from Repository” dialog. Select the files and their respective revisions you would like to restore and you’re done. Piece of pie.

Leave a Comment