[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[or-cvs] r18796: {torvm} More build updates, use Qt 4.5.0, add work-in-progress wixto (in torvm/trunk/build/win32: . files patches src/pkg)



Author: coderman
Date: 2009-03-07 10:52:50 -0500 (Sat, 07 Mar 2009)
New Revision: 18796

Added:
   torvm/trunk/build/win32/files/pkginfo.vbs
   torvm/trunk/build/win32/src/pkg/license.wxs
Modified:
   torvm/trunk/build/win32/Makefile
   torvm/trunk/build/win32/files/buildall.sh
   torvm/trunk/build/win32/patches/qt-mingwssl.patch
   torvm/trunk/build/win32/patches/vidalia-torvm.patch
Log:
More build updates, use Qt 4.5.0, add work-in-progress wixtool patch until ready for vidalia tree, Use new WiX transforms for localized packages, include new License / legal document package for bundle / Thandy use.

Modified: torvm/trunk/build/win32/Makefile
===================================================================
--- torvm/trunk/build/win32/Makefile	2009-03-07 08:53:18 UTC (rev 18795)
+++ torvm/trunk/build/win32/Makefile	2009-03-07 15:52:50 UTC (rev 18796)
@@ -198,11 +198,10 @@
 WINDDK_URL=http://download.microsoft.com/download/9/0/f/90f019ac-8243-48d3-91cf-81fc4093ecfd/$(WINDDK_F)
 WINDDK_SUM=0d2154d88a5ee252cc908630c77863bb42777387
 
-QT_VER=4.4.3
-QT_F=qt-win-opensource-src-$(QT_VER).zip
-QT_TGZ=qt-$(QT_VER).tgz
-QT_URL=ftp://ftp.trolltech.com/qt/source/qt-win-opensource-src-$(QT_VER).zip
-QT_SUM=669d494b9c37353f87c13765ed9f3ea97c0fa9e0
+QT_VER=4.5.0
+QT_F=qt-all-opensource-src-$(QT_VER).tar.bz2
+QT_URL=ftp://ftp.qtsoftware.com/qt/source/$(QT_F)
+QT_SUM=51dc8c66bc0866e480e71b50a8ffe577b2937fcc
 
 POLIPO_F=polipo-20080907.tar.gz
 POLIPO_URL=http://www.pps.jussieu.fr/~jch/software/files/polipo/$(POLIPO_F)
@@ -218,20 +217,20 @@
 VIDALIA_TGZ=$(VIDALIA_NAME).tar.gz
 VIDALIA_SVN=https://svn.vidalia-project.net/svn/vidalia/
 VIDALIA_BR=trunk
-VIDALIA_VER=3597
+VIDALIA_VER=3601
 
 # for package resources
 TORSVN_NAME=tor-latest
 TORSVN_TGZ=$(TORSVN_NAME).tar.gz
 TORSVN_SVN=https://tor-svn.freehaven.net/svn/tor/
 TORSVN_BR=trunk
-TORSVN_VER=18546
+TORSVN_VER=18791
 
 TORBUTTON_NAME=torbutton-latest
 TORBUTTON_TGZ=$(TORBUTTON_NAME).tar.gz
 TORBUTTON_SVN=https://tor-svn.freehaven.net/svn/torbutton/
 TORBUTTON_BR=trunk
-TORBUTTON_VER=18548
+TORBUTTON_VER=18788
 
 # XXX add / switch to signed tags one key mgmt resolved
 PYCRYPTO_NAME=pycrypto-latest
@@ -345,6 +344,7 @@
 	echo "export SEVNZIP_PKG=$(SEVNZIP_OPT_PKG)" >> $(ISODIR)/bldopts; \
 	echo "--- Copying packages for ISO image file system ..."; \
 	cp files/autorun.inf files/install.bat $(ISODIR)/; \
+	cp files/*.vbs $(ISODIR)/bin/; \
 	cp files/hdd.img.gz $(ISODIR)/add/; \
 	gzip -d $(ISODIR)/add/hdd.img.gz; \
 	cp files/fstab $(ISODIR)/bin/; \
@@ -370,6 +370,7 @@
 	mv $(ISODIR)/dl/$(ZLIBSRC_F) $(ISODIR)/dl/src/; \
 	mv $(ISODIR)/dl/$(LIBEVENT_F) $(ISODIR)/dl/src/; \
 	mv $(ISODIR)/dl/$(PYTHON_F) $(ISODIR)/dl/src/; \
+	mv $(ISODIR)/dl/$(QT_F) $(ISODIR)/dl/src/; \
 	echo "--- Repacking WinPCAP archive ..."; \
 	$(UNZIP) $(WDLDIR)/$(WPCAPSRC_F); mv winpcap WpcapSrc_$(WPCAPSRC_VER); tar cf $(ISODIR)/dl/src/WpcapSrc_$(WPCAPSRC_VER).tar WpcapSrc_$(WPCAPSRC_VER); gzip -9 $(ISODIR)/dl/src/WpcapSrc_$(WPCAPSRC_VER).tar; rm -rf WpcapSrc_$(WPCAPSRC_VER) $(ISODIR)/dl/$(WPCAPSRC_F); \
 	echo "--- Repacking Py2Exe archive ..."; \
@@ -380,8 +381,6 @@
 	$(UNZIP) $(WDLDIR)/$(WIX_F) -d wix; tar zcf $(ISODIR)/dl/$(WIX_TGZ) wix; rm -rf wix $(ISODIR)/dl/$(WIX_F); \
 	echo "--- Repacking WiX sources archive ..."; \
 	$(UNZIP) $(WDLDIR)/$(WIXSRC_F) -d wixsrc; tar zcf $(ISODIR)/dl/$(WIXSRC_TGZ) wixsrc; rm -rf wixsrc $(ISODIR)/dl/$(WIXSRC_F); \
-	echo "--- Repacking Qt archive ..."; \
-	$(UNZIP) $(WDLDIR)/$(QT_F) -d qt-$(QT_VER); mv qt-$(QT_VER)/qt-*/* qt-$(QT_VER)/; rm -rf qt-$(QT_VER)/qt-*; tar zcf $(ISODIR)/dl/src/$(QT_TGZ) qt-$(QT_VER); rm -rf qt-$(QT_VER) $(ISODIR)/dl/$(QT_F); \
 	echo "--- Exporting Vidalia version $(VIDALIA_VER) from local mirror ..."; \
 	rm -rf $(VIDALIA_NAME); $(SVNCMD) export --revision $(VIDALIA_VER) $(SDLDIR)/$(VIDALIA_NAME) $(VIDALIA_NAME); \
 	tar zcf $(ISODIR)/dl/src/$(VIDALIA_TGZ) $(VIDALIA_NAME); rm -rf $(VIDALIA_NAME); \

Modified: torvm/trunk/build/win32/files/buildall.sh
===================================================================
--- torvm/trunk/build/win32/files/buildall.sh	2009-03-07 08:53:18 UTC (rev 18795)
+++ torvm/trunk/build/win32/files/buildall.sh	2009-03-07 15:52:50 UTC (rev 18796)
@@ -64,6 +64,7 @@
   export instdir="${brootdir}/Installer"
   export thandir="${brootdir}/Thandy"
   export bundledir="${brootdir}/Bundle"
+  export licensedir="${brootdir}/License"
   
   if [[ "$SEVNZIP_INST" == "" ]]; then
     export SEVNZIP_INST=true
@@ -118,12 +119,12 @@
   export CMAKEBIN="/$sysdrive/Program Files/CMake/bin"
   export PATH="${PATH}:${CMAKEBIN}:/src/$CMAKE_DIR/bin"
   
-  export QT_VER="4.4.3"
-  export QT_DIR="qt-${QT_VER}"
-  export QT_FILE="qt-${QT_VER}.tgz"
+  export QT_VER="4.5.0"
+  export QT_DIR="qt-all-opensource-src-${QT_VER}"
+  export QT_FILE="${QT_DIR}.tar.bz2"
   export QT_ROOT="/$sysdrive/Qt/${QT_VER}"
   export QT_BIN="${QT_ROOT}/bin"
-  export QTDIR="${sysdrive}:\Qt\4.4.3"
+  export QTDIR="${sysdrive}:\Qt\4.5.0"
   export QMAKESPEC=win32-g++
   export PATH="$PATH:$QT_BIN:$QTDIR\bin"
   
@@ -133,7 +134,7 @@
   export MARBLE_DIR=marble-latest
   export MARBLE_FILE="${MARBLE_DIR}.tar.gz"
   export MARBLE_DEST=/marble
-  export MARBLE_OPTS="-DQTONLY=ON -DCMAKE_INSTALL_PREFIX=${MARBLE_DEST} -DPACKAGE_ROOT_PREFIX=${MARBLE_DEST} -DMARBLE_DATA_PATH=data"
+  export MARBLE_OPTS="-DCMAKE_BUILD_TYPE=release -DQTONLY=ON -DCMAKE_INSTALL_PREFIX=${MARBLE_DEST} -DPACKAGE_ROOT_PREFIX=${MARBLE_DEST} -DMARBLE_DATA_PATH=data"
   
   export VIDALIA_FILE=vidalia-latest.tar.gz
   export VIDALIA_DIR=vidalia-latest
@@ -227,7 +228,7 @@
     chmod 600 ~/.ssh/id_rsa >/dev/null 2>&1
   fi
 
-  for dir in $ddir $bdlibdir $bindir $statedir $brootdir $instdir $thandir $bundledir; do
+  for dir in $ddir $bdlibdir $bindir $statedir $brootdir $instdir $thandir $bundledir $licensedir; do
     if [ ! -d $dir ]; then
       mkdir -p $dir
     fi
@@ -351,6 +352,8 @@
   cp *.dll /bin/
   cp *.h /usr/include/
   cp pthreadGC2.dll $bdlibdir/
+  cp COPYING.LIB $licensedir/pthreads-w32-COPYING-LIB.txt
+  cp COPYING $licensedir/pthreads-w32-COPYING.txt
 
   pkgbuilt PTHREADS_BUILT
 fi
@@ -382,6 +385,7 @@
     exit 1
   fi
   cp *.dll $bdlibdir/
+  cp README $licensedir/zlib-README.txt
 
   pkgbuilt ZLIB_BUILT
 fi
@@ -403,6 +407,7 @@
     exit 1
   fi
   make install
+  # XXX license info is per file
 
   pkgbuilt LIBEVENT_BUILT
 fi
@@ -425,6 +430,7 @@
   fi
   make install
   cp /usr/bin/SDL.dll $bdlibdir/
+  cp COPYING $licensedir/SDL-COPYING.txt
 
   pkgbuilt SDL_BUILT
 fi
@@ -470,6 +476,8 @@
   fi
   cp i386/${TAPDRVN}.sys $bdlibdir/
   cp i386/OemWin2k.inf $bdlibdir/${TAPDRVN}.inf
+  cp COPYING $licensedir/openvpn-COPYING.txt
+  cp COPYRIGHT.GPL $licensedir/openvpn-COPYRIGHT-GPL.txt
 
   pkgbuilt OPENVPN_BUILT
 fi
@@ -707,6 +715,7 @@
       fi
     done
   )
+  mkdir pkgdocs
   ls -lh Usage.html
   for FILE in README ChangeLog LICENSE Authors src/config/torrc.sample; do
     if [ -f $FILE ]; then
@@ -715,6 +724,7 @@
       # must have the file present or the WiX MSI build fails
       echo > $FILE
     fi
+    cp $FILE pkgdocs/
   done
 
   pkgbuilt TOR_BUILT
@@ -810,7 +820,7 @@
   echo "Building Qt ..."
   cd /usr/src
   mkdir /$sysdrive/Qt
-  tar zxf $QT_FILE
+  tar jxf $QT_FILE
   mv $QT_DIR /$sysdrive/Qt/$QT_VER
   cd /$sysdrive/Qt/$QT_VER
   if [ -f /src/qt-mingwssl.patch ]; then
@@ -818,7 +828,7 @@
   fi 
   QT_CONF="-confirm-license -release -shared"
   QT_CONF="$QT_CONF -no-dbus -no-phonon -no-webkit -no-qdbus -no-opengl -no-qt3support -no-xmlpatterns"
-  QT_CONF="$QT_CONF -qt-style-windowsxp -qt-style-windowsvista"
+  QT_CONF="$QT_CONF -qt-style-windowsxp -no-style-windowsvista"
   QT_CONF="$QT_CONF -no-sql-sqlite -no-sql-sqlite2 -no-sql-odbc"
   QT_CONF="$QT_CONF -no-fast -openssl -no-libmng -no-libtiff -qt-libpng -qt-libjpeg -qt-gif"
   ./configure.exe $QT_CONF
@@ -835,12 +845,12 @@
     fi
   fi
 
-  # so it seems some things (marble) want to try and load
+  # XXX: so it seems some things (marble) want to try and load
   # image plugins that are not plugins, namely the .a libtool
   # hooks for linking DLL's in mingw.  this is a hammer to
   # prevent such mistakes that will halt an automated build with
-  # "Error not a library" warning when they try to OpenLibrary
-  # XXX Marble just needs a patch or config tweak to not do this.
+  # "Error not a library" warnings when a static lib is passed
+  # to OpenLibrary.
   find plugins/imageformats -name \*.a -exec rm {} \;
 
   pkgbuilt QT_BUILT
@@ -962,15 +972,13 @@
 
 
 # Microsoft Installer package build
-TOR_WXS=tor.wxs
-TORUI_WXS=WixUI_Tor.wxs
 TOR_WXS_DIR=contrib
 WIX_UI=/wix/WixUIExtension.dll
 WIXSRC_WXLDIR=/src/$WIXSRC_DIR/src/ext/UIExtension/wixlib
 DEF_WXL_LANG=en-us
-WXL_LANGS="cs-cz de-de en-us es-es fr-fr hu-hu it-it ja-jp nl-nl pl-pl ru-ru uk-ua"
+WXL_LANGS="cs-cz de-de es-es fr-fr hu-hu it-it ja-jp nl-nl pl-pl ru-ru uk-ua en-us"
 # XXX currently problems with WiX handling of: zh_CN zh_TW
-VIDALIA_LANGS="cs de en es fa fi fr he it nl pl pt ro ru sv"
+VIDALIA_LANGS="cs de es fa fi fr he it nl pl pt ro ru sv en"
 WIX_ALL_LOC_LINK=""
 for LANG in $WXL_LANGS; do
   WIX_ALL_LOC_LINK="${WIX_ALL_LOC_LINK} -loc WixUI_${LANG}.wxl"
@@ -979,9 +987,8 @@
   WIX_ALL_LOC_LINK="${WIX_ALL_LOC_LINK} -loc vidalia_${LANG}.wxl"
 done
 
-# XXX for now this eats up too much time and space
-# rely on the multi-lingual packages if possible.
-BUILD_IND_LANGS=no
+# XXX building all languages eats up too much time and space
+BUILD_IND_LANGS=yes
 
 if [[ "$PACKAGES_BUILT" != "yes" ]]; then
   echo "Building bundle packages ..."
@@ -1015,6 +1022,14 @@
       strip bin/*.exe
     fi
 
+    # typical work flow using generated component fragments from heat.exe:
+    # heat.exe dir $pkgdir -gg -ke -sfrag -nologo -out "${pkgdir}.wxs" -template:product
+    # tail +4c $out > $tmp, dos2unix $tmp
+    # wixtool.exe splice -i prod.wxs -o out.wxs Directory:DirName=heat.wxs:Directory:dirname
+    # wixtool.exe splice -i out.wxs -o final.wxs Feature:MainApplication=heat.wxs:Feature:ProductFeature
+    # light.exe -sloc -out vid.wixout -xo -cc cabcache WixUI_Custom.wixobj vidalia.wixobj -ext /wix/WixUIExtension.dll
+    # light.exe "-cultures:es-es;de-de;en-us" -loc WixUI_es-es.wxl -loc WixUI_de-de.wxl -loc WixUI_en-us.wxl -loc vidalia_es.wxl -loc vidalia_de.wxl -loc vidalia_en.wxl -out test.msi -cc cabcache -reusecab vid.wixout
+
     cp $WIXSRC_WXLDIR/*.wxl ./
     cp pkg/win32/*.wxl ./
     candle.exe pkg/win32/*.wxs
@@ -1027,6 +1042,10 @@
     else
       echo "ERROR: unable to build vidalia MSI installer."
     fi
+    light.exe -out vidalia-intl.msi vidalia.wixobj WixUI_Custom.wixobj -sloc -ext $WIX_UI
+    if [ -f vidalia-intl.msi ]; then
+      export BASEMSI=vidalia-intl.msi
+    fi
     if [[ "$BUILD_IND_LANGS" == "yes" ]]; then
       for LANG in $VIDALIA_LANGS; do
         WIXCULTURE=$DEF_WXL_LANG
@@ -1043,17 +1062,29 @@
           cp $outfile $bundledir
           cp $outfile ../pkg/
           ls -l $outfile
+          if [ -f $BASEMSI ]; then
+            echo "Adding language $LANG as transform against minimal MSI package ..."
+            cscript.exe mktransform.vbs "$LANG" "$BASEMSI" "$outfile"
+          fi
         else
           echo "ERROR: unable to link localized $outfile vidalia MSI installer."
         fi
       done
+      if [ -f $BASEMSI ]; then
+        cp $BASEMSI ../pkg/
+      fi
     fi
   fi
   cd /usr/src/pkg
   echo "Copying various package dependencies into place ..."
   cp $WIXSRC_WXLDIR/*.wxl ./
+  cp /src/$VIDALIA_DIR/src/tools/wixtool/wixtool.exe ./
+  cp /src/$VIDALIA_DIR/pkg/win32/*.bmp ./
+  cp /src/$VIDALIA_DIR/pkg/win32/*.vbs ./
+  cp /src/$VIDALIA_DIR/pkg/win32/*.wxs ./
   cp /src/$VIDALIA_DIR/pkg/win32/*.wxl ./
   cp ../torvm-w32/tor-icon-32.ico ./torvm.ico
+  cp ../torvm-w32/tor-icon-32.ico ./tor.ico
   # DONT STRIP PY2EXEs!
   cp $thandir/Thandy.exe bin/
   cp /src/$TOR_DIR/contrib/*.wxs ./
@@ -1061,9 +1092,9 @@
   mkdir -p src/config
   mkdir -p share/tor
   mkdir -p contrib
-  cp /src/$TOR_DIR/contrib/*.ico contrib/
-  cp /src/$TOR_DIR/share/tor/geoip share/tor/
-  cp /src/$TOR_DIR/src/config/torrc.sample src/config/
+  cp /src/$TOR_DIR/contrib/*.ico ./
+  cp /src/$TOR_DIR/share/tor/geoip ./
+  cp /src/$TOR_DIR/src/config/torrc.sample ./
   for FNAME in README Usage.html Authors ChangeLog LICENSE; do
     cp /src/$TOR_DIR/$FNAME ./
   done
@@ -1071,53 +1102,247 @@
   # XXX replace this with Matt's torbutton NSIS magic
   candle.exe *.wxs
 
+  echo "Building Tor Vidalia bundle license docs package ..."
+  (
+    cd $licensedir;cd ../
+    heat.exe dir License -gg -ke -sfrag -nologo -out license-dir.wxs -template:product
+    if [ -f license-dir.wxs ]; then mv license-dir.wxs /src/pkg/; fi
+  )
+  if [ ! -f license-dir.wxs ]; then
+    echo "Failed to generate directory tree component for $licensedir ."
+  else
+    # whatever WiX is putting in those first four bytes causes parser havoc
+    tail +4c license-dir.wxs > license-dir.wxs.tmp; dos2unix license-dir.wxs.tmp; cat license-dir.wxs.tmp > license-dir.wxs; rm -f license-dir.wxs.tmp
+    wixtool.exe splice -i license.wxs -o license-tmpdir.wxs Directory:ProgramsInstDir=license-dir.wxs:Directory:License
+    wixtool.exe splice -i license-tmpdir.wxs -o license-all.wxs Feature:MainApplication=license-dir.wxs:Feature:ProductFeature
+    rm -f license-tmpdir.wxs
+    candle.exe license-all.wxs
+    echo "Linking Tor Vidalia bundle license docs package ..."
+    light.exe -out license.msi WixUI_Custom.wixobj license-all.wixobj $WIX_ALL_LOC_LINK -ext $WIX_UI
+  fi
+
   echo "Linking torvm MSI installer package ..."
-  light.exe -out torvm.msi WixUI_Tor.wixobj torvm.wixobj $WIX_ALL_LOC_LINK -ext $WIX_UI
+  light.exe -out torvm.msi WixUI_Custom.wixobj torvm.wixobj $WIX_ALL_LOC_LINK -ext $WIX_UI
   if [ -f torvm.msi ]; then
     cp torvm.msi $bundledir
     ls -l torvm.msi
   else
     echo "ERROR: unable to build Tor VM MSI installer."
   fi
+  echo "Linking minimal zero codepage MSI installer package ..."
+  light.exe -out torvm-intl.msi WixUI_Custom.wixobj torvm.wixobj -sloc -ext $WIX_UI
+  if [ -f torvm-intl.msi ]; then
+    export BASEMSI=torvm-intl.msi
+  else
+    echo "ERROR: unable to link minimal zero codepage Tor VM MSI installer."
+    export BASEMSI=""
+  fi
+  if [[ "$BUILD_IND_LANGS" == "yes" ]]; then
+    for LANG in $VIDALIA_LANGS; do
+      WIXCULTURE=$DEF_WXL_LANG
+      for WIXLANG in $WXL_LANGS; do
+        pre=$(echo $WIXLANG | sed 's/-.*//')
+        if [[ "$pre" == "$LANG" ]]; then
+          WIXCULTURE=$WIXLANG
+        fi 
+      done 
+      outfile="torvm-${LANG}.msi"
+      echo "Linking localized $outfile ..."
+      light.exe -out $outfile torvm.wixobj WixUI_Custom.wixobj -cultures:$WIXCULTURE -loc "vidalia_${LANG}.wxl" -ext $WIX_UI
+      if [ -f $outfile ]; then
+        cp $outfile $bundledir
+        ls -l $outfile
+        if [ -f "$BASEMSI" ]; then
+          echo "Adding language $LANG as transform against minimal MSI package ..."
+          cscript.exe mktransform.vbs "$LANG" "$BASEMSI" "$outfile"
+        fi
+      else
+        echo "ERROR: unable to link localized $outfile MSI installer."
+      fi
+    done
+  fi
+  if [ -f "$BASEMSI" ]; then
+    cp "$BASEMSI" $bundledir
+  fi
 
   echo "Linking tor MSI installer package ..."
-  light.exe -out tor.msi WixUI_Tor.wixobj tor.wixobj $WIX_ALL_LOC_LINK -ext $WIX_UI
+  light.exe -out tor.msi WixUI_Custom.wixobj tor.wixobj $WIX_ALL_LOC_LINK -ext $WIX_UI
   if [ -f tor.msi ]; then
     cp tor.msi $bundledir
     ls -l tor.msi
   else
     echo "ERROR: unable to build Tor MSI installer."
   fi
+  echo "Linking minimal zero codepage MSI installer package ..."
+  light.exe -out tor-intl.msi WixUI_Custom.wixobj tor.wixobj -sloc -ext $WIX_UI
+  if [ -f tor-intl.msi ]; then
+    export BASEMSI=tor-intl.msi
+  else
+    echo "ERROR: unable to link minimal zero codepage Tor VM MSI installer."
+    export BASEMSI=""
+  fi
+  if [[ "$BUILD_IND_LANGS" == "yes" ]]; then
+    for LANG in $VIDALIA_LANGS; do
+      WIXCULTURE=$DEF_WXL_LANG
+      for WIXLANG in $WXL_LANGS; do
+        pre=$(echo $WIXLANG | sed 's/-.*//')
+        if [[ "$pre" == "$LANG" ]]; then
+          WIXCULTURE=$WIXLANG
+        fi 
+      done 
+      outfile="tor-${LANG}.msi"
+      echo "Linking localized $outfile ..."
+      light.exe -out $outfile tor.wixobj WixUI_Custom.wixobj -cultures:$WIXCULTURE -loc "vidalia_${LANG}.wxl" -ext $WIX_UI
+      if [ -f $outfile ]; then
+        cp $outfile $bundledir
+        ls -l $outfile
+        if [ -f "$BASEMSI" ]; then
+          echo "Adding language $LANG as transform against minimal MSI package ..."
+          cscript.exe mktransform.vbs "$LANG" "$BASEMSI" "$outfile"
+        fi
+      else
+        echo "ERROR: unable to link localized $outfile MSI installer."
+      fi
+    done
+  fi
+  if [ -f "$BASEMSI" ]; then
+    cp "$BASEMSI" $bundledir
+  fi
 
   echo "Linking polipo MSI installer package ..."
-  light.exe -out polipo.msi WixUI_Tor.wixobj polipo.wixobj $WIX_ALL_LOC_LINK -ext $WIX_UI
+  light.exe -out polipo.msi WixUI_Custom.wixobj polipo.wixobj $WIX_ALL_LOC_LINK -ext $WIX_UI
   if [ -f polipo.msi ]; then
     cp polipo.msi $bundledir
     ls -l polipo.msi
   else
     echo "ERROR: unable to build polipo MSI installer."
   fi
+  echo "Linking minimal zero codepage MSI installer package ..."
+  light.exe -out polipo-intl.msi WixUI_Custom.wixobj polipo.wixobj -sloc -ext $WIX_UI
+  if [ -f polipo-intl.msi ]; then
+    export BASEMSI=polipo-intl.msi
+  else
+    echo "ERROR: unable to link minimal zero codepage Polipo MSI installer."
+    export BASEMSI=""
+  fi
+  if [[ "$BUILD_IND_LANGS" == "yes" ]]; then
+    for LANG in $VIDALIA_LANGS; do
+      WIXCULTURE=$DEF_WXL_LANG
+      for WIXLANG in $WXL_LANGS; do
+        pre=$(echo $WIXLANG | sed 's/-.*//')
+        if [[ "$pre" == "$LANG" ]]; then
+          WIXCULTURE=$WIXLANG
+        fi
+      done 
+      outfile="polipo-${LANG}.msi"
+      echo "Linking localized $outfile ..."
+      light.exe -out $outfile polipo.wixobj WixUI_Custom.wixobj -cultures:$WIXCULTURE -loc "vidalia_${LANG}.wxl" -ext $WIX_UI
+      if [ -f $outfile ]; then
+        cp $outfile $bundledir
+        ls -l $outfile
+        if [ -f "$BASEMSI" ]; then
+          echo "Adding language $LANG as transform against minimal MSI package ..."
+          cscript.exe mktransform.vbs "$LANG" "$BASEMSI" "$outfile"
+        fi
+      else
+        echo "ERROR: unable to link localized $outfile MSI installer."
+      fi
+    done
+  fi
+  if [ -f "$BASEMSI" ]; then
+    cp "$BASEMSI" $bundledir
+  fi
 
   if [ -f /src/$TORBUTTON_FILE ]; then
     cp /src/$TORBUTTON_FILE torbutton.xpi
     echo "Linking torbutton MSI installer package ..."
-    light.exe -out torbutton.msi WixUI_Tor.wixobj torbutton.wixobj $WIX_ALL_LOC_LINK -ext $WIX_UI
+    light.exe -out torbutton.msi WixUI_Custom.wixobj torbutton.wixobj $WIX_ALL_LOC_LINK -ext $WIX_UI
     if [ -f torbutton.msi ]; then
       cp torbutton.msi $bundledir
       ls -l torbutton.msi
     else
       echo "ERROR: unable to build torbutton MSI installer."
     fi
+    echo "Linking minimal zero codepage MSI installer package ..."
+    light.exe -out torbutton-intl.msi WixUI_Custom.wixobj torbutton.wixobj -sloc -ext $WIX_UI
+    if [ -f torbutton-intl.msi ]; then
+      export BASEMSI=torbutton-intl.msi
+    else
+      echo "ERROR: unable to link minimal zero codepage TorButton MSI installer."
+      export BASEMSI=""
+    fi
+    if [[ "$BUILD_IND_LANGS" == "yes" ]]; then
+      for LANG in $VIDALIA_LANGS; do
+        WIXCULTURE=$DEF_WXL_LANG 
+        for WIXLANG in $WXL_LANGS; do
+          pre=$(echo $WIXLANG | sed 's/-.*//')
+          if [[ "$pre" == "$LANG" ]]; then
+            WIXCULTURE=$WIXLANG
+          fi
+        done
+        outfile="torbutton-${LANG}.msi"
+        echo "Linking localized $outfile ..."
+        light.exe -out $outfile torbutton.wixobj WixUI_Custom.wixobj -cultures:$WIXCULTURE -loc "vidalia_${LANG}.wxl" -ext $WIX_UI
+        if [ -f $outfile ]; then
+          cp $outfile $bundledir
+          ls -l $outfile
+          if [ -f "$BASEMSI" ]; then
+            echo "Adding language $LANG as transform against minimal MSI package ..."
+            cscript.exe mktransform.vbs "$LANG" "$BASEMSI" "$outfile"
+          fi
+        else
+          echo "ERROR: unable to link localized $outfile MSI installer."
+        fi
+      done
+    fi
+    if [ -f "$BASEMSI" ]; then
+      cp "$BASEMSI" $bundledir
+    fi
   fi
 
   echo "Linking thandy MSI installer package ..."
-  light.exe -out thandy.msi WixUI_Tor.wixobj thandy.wixobj $WIX_ALL_LOC_LINK -ext $WIX_UI
+  light.exe -out thandy.msi WixUI_Custom.wixobj thandy.wixobj $WIX_ALL_LOC_LINK -ext $WIX_UI
   if [ -f thandy.msi ]; then
     cp thandy.msi $bundledir
     ls -l thandy.msi
   else
     echo "ERROR: unable to build Thandy MSI installer."
   fi
+  echo "Linking minimal zero codepage MSI installer package ..."
+  light.exe -out thandy-intl.msi WixUI_Custom.wixobj thandy.wixobj -sloc -ext $WIX_UI
+  if [ -f thandy-intl.msi ]; then
+    export BASEMSI=thandy-intl.msi
+  else
+    echo "ERROR: unable to link minimal zero codepage Thandy MSI installer."
+    export BASEMSI=""
+  fi
+  if [[ "$BUILD_IND_LANGS" == "yes" ]]; then
+    for LANG in $VIDALIA_LANGS; do
+      WIXCULTURE=$DEF_WXL_LANG 
+      for WIXLANG in $WXL_LANGS; do
+        pre=$(echo $WIXLANG | sed 's/-.*//')
+        if [[ "$pre" == "$LANG" ]]; then
+          WIXCULTURE=$WIXLANG
+        fi
+      done
+      outfile="thandy-${LANG}.msi"
+      echo "Linking localized $outfile ..."
+      light.exe -out $outfile thandy.wixobj WixUI_Custom.wixobj -cultures:$WIXCULTURE -loc "vidalia_${LANG}.wxl" -ext $WIX_UI
+      if [ -f $outfile ]; then
+        cp $outfile $bundledir
+        ls -l $outfile
+        if [ -f "$BASEMSI" ]; then
+          echo "Adding language $LANG as transform against minimal MSI package ..."
+          cscript.exe mktransform.vbs "$LANG" "$BASEMSI" "$outfile"
+        fi
+      else
+        echo "ERROR: unable to link localized $outfile MSI installer."
+      fi
+    done
+  fi
+  if [ -f "$BASEMSI" ]; then
+    cp "$BASEMSI" $bundledir
+  fi
 
   echo "Creating Tor VM bundle installer executable ..."
   makensis.exe bundle.nsi

Added: torvm/trunk/build/win32/files/pkginfo.vbs
===================================================================
--- torvm/trunk/build/win32/files/pkginfo.vbs	                        (rev 0)
+++ torvm/trunk/build/win32/files/pkginfo.vbs	2009-03-07 15:52:50 UTC (rev 18796)
@@ -0,0 +1,65 @@
+' Copyright (C) 2009  The Tor Project, Inc.
+' See LICENSE file for rights and terms.
+'
+' Script to generate an XML description of all installed
+' products and packages.
+'   Ex.: cscript.exe //Nologo pkginfo.vbs > pkginfo.xml
+'
+Option Explicit
+Const msiInstallStateBadConfig    = -6
+Const msiInstallStateInvalidArg   = -2
+Const msiInstallStateUnknown      = -1
+Const msiInstallStateAdvertised   =  1
+Const msiInstallStateAbsent       =  2
+Const msiInstallStateDefault      =  5
+'
+' Connect to Windows Installer object and list package details
+Dim installer
+Set installer = Wscript.CreateObject("WindowsInstaller.Installer")
+Dim product, products
+Dim productState
+Set products = installer.Products
+For Each product In products
+  WScript.Echo GenerateProductElement()
+  WScript.Echo GeneratePackageElement()
+  WScript.Echo "</Product>" & vbCrLf
+Next
+'
+' All done.
+Set products = Nothing
+Set installer = Nothing
+Wscript.Quit 0
+'
+' Helper functions
+Function GenerateProductElement()
+  Dim script
+  script = "<Product Id=""" & product & """" & vbCrLf
+  script = script & ProductProperty("InstalledProductName", "Name", 6) & vbCrLf
+  script = script & ProductProperty("VersionString", "Version", 6) & vbCrLf
+  script = script & ProductProperty("InstallDate", "InstalledOn", 6) & vbCrLf
+  script = script & Space(6) & "State="""
+  Select Case installer.ProductState(product)
+    Case msiInstallStateAbsent:
+      script = script & "LocalDifferentUser"
+    Case msiInstallStateDefault:
+      script = script & "LocalCurrentUser"
+    Case msiInstallStateAdvertised:
+      script = script & "Advertised"
+    Case msiInstallStateBadConfig:
+      script = script & "Corrupt"
+  End Select
+  script = script & """" & vbCrLf
+  script = script & ProductProperty("InstallSource", "InstalledFrom", 6) & vbCrLf
+  script = script & ProductProperty("LocalPackage", "LocalPackage", 6)
+  GenerateProductElement = script & ">"
+End Function
+
+Function GeneratePackageElement()
+  Dim script
+  script = "   <Package " & ProductProperty("PackageCode", "Id", 0) & " />"
+  GeneratePackageElement = script
+End Function
+ 
+Function ProductProperty(attribute, name, indent)
+  ProductProperty = Space(indent) & name & "=""" & installer.ProductInfo(product, attribute) & """"
+End Function

Modified: torvm/trunk/build/win32/patches/qt-mingwssl.patch
===================================================================
--- torvm/trunk/build/win32/patches/qt-mingwssl.patch	2009-03-07 08:53:18 UTC (rev 18795)
+++ torvm/trunk/build/win32/patches/qt-mingwssl.patch	2009-03-07 15:52:50 UTC (rev 18796)
@@ -1,29 +1,32 @@
-diff -Naur orig-qt-4.4.3/src/network/ssl/qsslsocket_openssl_symbols.cpp mod-qt-4.4.3/src/network/ssl/qsslsocket_openssl_symbols.cpp
---- orig-qt-4.4.3/src/network/ssl/qsslsocket_openssl_symbols.cpp	2008-09-27 09:00:56.000000000 +0000
-+++ mod-qt-4.4.3/src/network/ssl/qsslsocket_openssl_symbols.cpp	2008-12-30 09:53:24.191484064 +0000
-@@ -327,14 +327,22 @@
-     if (!ssleay32->load()) {
-         // Cannot find ssleay32.dll
-         delete ssleay32;
--        return pair;
-+        ssleay32 = new QLibrary(QLatin1String("ssleay32-0.9.8"));
-+        if (!ssleay32->load()) {
-+            delete ssleay32;
-+            return pair;
-+        }
-     }
- 
-     QLibrary *libeay32 = new QLibrary(QLatin1String("libeay32"));
-     if (!libeay32->load()) {
--        delete ssleay32;
-         delete libeay32;
--        return pair;
-+        libeay32 = new QLibrary(QLatin1String("cryptoeay32-0.9.8"));
-+        if (!libeay32->load()) {
-+            delete libeay32;
-+            delete ssleay32;
-+            return pair;
-+        }
-     }
- 
-     pair.first = ssleay32;
+diff -Naur a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp
+--- a/src/network/ssl/qsslsocket_openssl_symbols.cpp	2009-02-25 21:32:38.000000000 +0000
++++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp	2009-03-06 16:14:07.852583592 +0000
+@@ -320,16 +320,24 @@
+ # ifdef Q_OS_WIN
+     QLibrary *ssleay32 = new QLibrary(QLatin1String("ssleay32"));
+     if (!ssleay32->load()) {
+-        // Cannot find ssleay32.dll
+         delete ssleay32;
+-        return pair;
++        ssleay32 = new QLibrary(QLatin1String("ssleay32-0.9.8"));
++        if (!ssleay32->load()) {
++            // Cannot find ssleay32.dll
++            delete ssleay32;
++            return pair;
++        }
+     }
+ 
+     QLibrary *libeay32 = new QLibrary(QLatin1String("libeay32"));
+     if (!libeay32->load()) {
+-        delete ssleay32;
+         delete libeay32;
+-        return pair;
++        libeay32 = new QLibrary(QLatin1String("cryptoeay32-0.9.8"));
++        if (!libeay32->load()) {
++            delete ssleay32;
++            delete libeay32;
++            return pair;
++        }
+     }
+ 
+     pair.first = ssleay32;

Modified: torvm/trunk/build/win32/patches/vidalia-torvm.patch
===================================================================
--- torvm/trunk/build/win32/patches/vidalia-torvm.patch	2009-03-07 08:53:18 UTC (rev 18795)
+++ torvm/trunk/build/win32/patches/vidalia-torvm.patch	2009-03-07 15:52:50 UTC (rev 18796)
@@ -1,19 +1,15 @@
 diff -Naur a/pkg/win32/polipo.conf b/pkg/win32/polipo.conf
 --- a/pkg/win32/polipo.conf	2008-04-06 00:00:07.066809000 +0000
-+++ b/pkg/win32/polipo.conf	2009-03-01 00:53:58.321690488 +0000
-@@ -36,8 +36,9 @@
++++ b/pkg/win32/polipo.conf	2009-03-07 12:47:21.712807024 +0000
+@@ -35,7 +35,6 @@
+ # parentProxy = "squid.example.org:3128"
  
  # Uncomment this if you want to use a parent SOCKS proxy:
+-
+ socksParentProxy = "localhost:9050"
+ socksProxyType = socks5
  
--socksParentProxy = "localhost:9050"
--socksProxyType = socks5
-+# For Tor VM we don't use an upstream proxy, just transparent
-+#socksParentProxy = "localhost:9050"
-+#socksProxyType = socks5
- 
- 
- ### Memory
-@@ -88,7 +89,7 @@
+@@ -88,7 +87,7 @@
  # Uncomment this if you want to contact IPv4 hosts only (and make DNS
  # queries somewhat faster):
  #
@@ -22,7 +18,7 @@
  
  # Uncomment this if you want Polipo to prefer IPv4 to IPv6 for
  # double-stack hosts:
-@@ -99,7 +100,9 @@
+@@ -99,7 +98,9 @@
  # default resolver instead.  If you do that, Polipo will freeze during
  # every DNS query:
  
@@ -35,8 +31,8 @@
  ### HTTP
 diff -Naur a/pkg/win32/vidalia.wxs.in b/pkg/win32/vidalia.wxs.in
 --- a/pkg/win32/vidalia.wxs.in	2009-02-24 05:46:46.615879000 +0000
-+++ b/pkg/win32/vidalia.wxs.in	2009-03-01 12:03:50.515548280 +0000
-@@ -1,260 +1,263 @@
++++ b/pkg/win32/vidalia.wxs.in	2009-03-07 03:57:41.691104680 +0000
+@@ -1,260 +1,275 @@
  <?xml version="1.0" encoding="Windows-1252" ?>
  <!-- 
 -  $Id: vidalia.wxs.in 3586 2009-02-24 05:46:46Z edmanm $
@@ -74,6 +70,7 @@
 +  <?define CurrPolipoConfigGUID="2151ad60-10ce-4e91-ab44-d1895d3b001d" ?>
 +  <?define CurrMarblePluginGUID="0212a411-960d-4729-b03b-3c95777a4551" ?>
 +  <?define CurrPluginDataDirGUID="e72719f3-e92c-4b2c-a8bb-4865436f5734" ?>
++  <?define CurrPluginImageFormatsGUID="26ad5c24-249d-4619-be36-fb701e5b3f81" ?>
 +  <?define CurrDocumentsGUID="abfaae86-352e-4b63-b9b3-c222936f24b3" ?>
 +  <?define CurrConfigFileGUID="4428ffd8-710d-4550-b51d-16e69e073981" ?>
 +  <?define CurrStartMenuGUID="69d3f4bb-755c-4ade-aeb1-771fd5f8ba60" ?>
@@ -500,6 +497,17 @@
 +                </RegistryKey>
 +              </Component>
 +            </Directory>
++            <Directory Id="LocalPluginsImageFormatsDir" Name="imageformats">
++              <Component Id="PluginImageFormatsDir" Guid="$(var.CurrPluginImageFormatsGUID)">
++                <CreateFolder/>
++                <RemoveFolder Id="RemoveLocalPluginsImageFormatsDir" On="uninstall" />
++                <RegistryKey Root="HKCU" Key="Software\Vidalia" Action="createAndRemoveOnUninstall">
++                  <RegistryValue Name="PluginImageFormatsDir" Value="1" Type="integer" KeyPath="yes" />
++                </RegistryKey>
++                <File Id="qsvg4.dll" DiskId="1"
++                  Name="qsvg4.dll" Source="plugins/imageformats/qsvg4.dll" />
++              </Component>
++            </Directory>
 +          </Directory>
 +        </Directory>
 +      </Directory>
@@ -526,7 +534,7 @@
                        Icon="vidalia.ico" IconIndex="0" />
              <RemoveFolder Id="RemoveShortcutFolder" On="uninstall" />
            </Component>
-@@ -262,73 +265,79 @@
+@@ -262,73 +277,80 @@
        </Directory>
  
        <Directory Id="DesktopFolder" Name="Desktop">
@@ -585,6 +593,7 @@
 +        <ComponentRef Id="PolipoConfig" />
 +        <ComponentRef Id="MarblePlugin" />
 +        <ComponentRef Id="PluginDataDir" />
++        <ComponentRef Id="PluginImageFormatsDir" />
        </Feature>
        <Feature Id="Shortcuts" Title="Shortcuts"
                 AllowAdvertise="no" Absent="allow" Level="1"
@@ -629,7 +638,7 @@
  </Wix>
 diff -Naur a/src/common/win32.cpp b/src/common/win32.cpp
 --- a/src/common/win32.cpp	2009-02-16 22:53:13.437184000 +0000
-+++ b/src/common/win32.cpp	2009-03-01 00:53:58.321690488 +0000
++++ b/src/common/win32.cpp	2009-03-07 03:57:41.691104680 +0000
 @@ -67,16 +67,20 @@
  QString
  win32_program_files_folder()
@@ -655,9 +664,602 @@
  }
  
  /** Returns the value in keyName at keyLocation. 
+diff -Naur a/src/tools/CMakeLists.txt b/src/tools/CMakeLists.txt
+--- a/src/tools/CMakeLists.txt	2009-02-27 21:08:55.152739000 +0000
++++ b/src/tools/CMakeLists.txt	2009-03-07 02:42:35.594135000 +0000
+@@ -17,5 +17,6 @@
+   add_subdirectory(po2nsh)
+   add_subdirectory(nsh2po EXCLUDE_FROM_ALL)
+   add_subdirectory(po2wxl)
++  add_subdirectory(wixtool)
+ endif(WIN32)
+ 
+diff -Naur a/src/tools/po2wxl/po2wxl.cpp b/src/tools/po2wxl/po2wxl.cpp
+--- a/src/tools/po2wxl/po2wxl.cpp	2009-03-01 07:55:10.500878000 +0000
++++ b/src/tools/po2wxl/po2wxl.cpp	2009-03-07 03:57:41.692104528 +0000
+@@ -19,9 +19,49 @@
+ #define WXL_NAMESPACE                  "http://schemas.microsoft.com/wix/2006/localization";
+ #define WXL_ELEMENT_ROOT               "WixLocalization"
+ #define WXL_ELEMENT_MESSAGE            "String"
++#define WXL_ATTR_LANGUAGE              "LCID"
+ #define WXL_ATTR_MESSAGE_ID            "Id"
+ #define WXL_ATTR_TRANSLATION_TYPE      "Culture"
+-#define WXL_ATTR_OVERRIDABLE           "Overridable"
++
++/** We need to provide an element with the LCID for this locale 
++ * that is used in the WiX Product definition. */
++QString
++culture_lcid(const QString &culture)
++{
++  /* For now character encoding focused, not generally locale / dialect aware. */
++  QString lcid = "0";
++  if(!culture.compare("en", Qt::CaseInsensitive)) 
++    lcid = "1033";
++  else if(!culture.compare("cs", Qt::CaseInsensitive)) 
++    lcid = "1029";
++  else if(!culture.compare("de", Qt::CaseInsensitive)) 
++    lcid = "1031";
++  else if(!culture.compare("es", Qt::CaseInsensitive)) 
++    lcid = "1034";
++  else if(!culture.compare("fa", Qt::CaseInsensitive)) 
++    lcid = "1065";
++  else if(!culture.compare("fi", Qt::CaseInsensitive)) 
++    lcid = "1035";
++  else if(!culture.compare("fr", Qt::CaseInsensitive)) 
++    lcid = "1036";
++  else if(!culture.compare("he", Qt::CaseInsensitive)) 
++    lcid = "1037";
++  else if(!culture.compare("it", Qt::CaseInsensitive)) 
++    lcid = "1040";
++  else if(!culture.compare("nl", Qt::CaseInsensitive)) 
++    lcid = "1043";
++  else if(!culture.compare("pl", Qt::CaseInsensitive)) 
++    lcid = "1045";
++  else if(!culture.compare("pt", Qt::CaseInsensitive)) 
++    lcid = "1046";
++  else if(!culture.compare("ro", Qt::CaseInsensitive)) 
++    lcid = "1048";
++  else if(!culture.compare("ru", Qt::CaseInsensitive)) 
++    lcid = "1049";
++  else if(!culture.compare("sv", Qt::CaseInsensitive)) 
++    lcid = "1053";
++  return lcid;
++}
+ 
+ /** Create a new message string element using the source string <b>msgid</b>
+  * and the translation <b>msgstr</b> and assign identifier attribute. */
+@@ -33,11 +73,6 @@
+ 
+   message = wxl->createElement(WXL_ELEMENT_MESSAGE);
+   message.setAttribute(WXL_ATTR_MESSAGE_ID, strid);
+-
+-  /* Always allow localized string to be dynamic. This is required for
+-   * multi-language packages to link correctly.
+-   */
+-  message.setAttribute(WXL_ATTR_OVERRIDABLE, "yes");
+   if (!msgstr.isEmpty())
+     message.appendChild(wxl->createTextNode(msgstr));
+   else
+@@ -146,7 +181,12 @@
+   Q_ASSERT(errorMessage);
+ 
+   *wxl = new_wxl_document(culture);
+-  
++
++  /* Set the LCID to Language code for use as !(loc.LCID) in Product. */
++  QString lcid = culture_lcid(culture); 
++  wxl->documentElement().appendChild(
++    new_message_element(wxl, WXL_ATTR_LANGUAGE, lcid, lcid)); 
++
+   skip_po_header(po);
+   line = read_next_line(po);
+   while (!po->atEnd()) {
+diff -Naur a/src/tools/wixtool/CMakeLists.txt b/src/tools/wixtool/CMakeLists.txt
+--- a/src/tools/wixtool/CMakeLists.txt	1970-01-01 00:00:00.000000000 +0000
++++ b/src/tools/wixtool/CMakeLists.txt	2009-03-07 02:42:35.595135000 +0000
+@@ -0,0 +1,28 @@
++##
++##  $Id$
++## 
++##  This file is part of Vidalia, and is subject to the license terms in the
++##  LICENSE file, found in the top level directory of this distribution. If 
++##  you did not receive the LICENSE file with this file, you may obtain it
++##  from the Vidalia source package distributed by the Vidalia Project at
++##  http://www.vidalia-project.net/. No part of Vidalia, including this file,
++##  may be copied, modified, propagated, or distributed except according to
++##  the terms described in the LICENSE file.
++##
++
++## wixtool source files
++set(wixtool_SRCS
++  wixtool.cpp
++)
++
++## Create the wixtool executable
++add_executable(wixtool ${wixtool_SRCS})
++
++## Link the executable with the appropriate Qt libraries
++target_link_libraries(wixtool ${QT_LIBRARIES})
++
++## Remember location so we can use it in custom commands
++get_target_property(WIXTOOL_EXECUTABLE wixtool LOCATION)
++set(VIDALIA_WIXTOOL_EXECUTABLE ${WIXTOOL_EXECUTABLE}
++    CACHE STRING "Location of Vidalia's wixtool program." FORCE)
++
+diff -Naur a/src/tools/wixtool/wixtool.cpp b/src/tools/wixtool/wixtool.cpp
+--- a/src/tools/wixtool/wixtool.cpp	1970-01-01 00:00:00.000000000 +0000
++++ b/src/tools/wixtool/wixtool.cpp	2009-03-07 15:46:41.482073464 +0000
+@@ -0,0 +1,467 @@
++/*
++**  $Id$
++**
++**  This file is part of Vidalia, and is subject to the license terms in the
++**  LICENSE file, found in the top level directory of this distribution. If you
++**  did not receive the LICENSE file with this file, you may obtain it from the
++**  Vidalia source package distributed by the Vidalia Project at
++**  http://www.vidalia-project.net/. No part of Vidalia, including this file,
++**  may be copied, modified, propagated, or distributed except according to the
++**  terms described in the LICENSE file.
++*/
++
++#include <QFile>
++#include <QDomDocument>
++#include <QTextStream>
++#include <QTextCodec>
++#include <QStringList>
++#include <stdlib.h>
++
++#define WIX_ATTR_ID  "Id"
++#define WIX_ATTR_DIRACTION "uninstall"
++#define WIX_ATTR_REGACTION "createAndRemoveOnUninstall"
++
++typedef void (*TraverseCallback)(void *cbdata, QDomElement e);
++
++typedef struct s_SpliceData {
++  QString      dtag;
++  QString      did;
++  QDomElement  splice;
++} SpliceData;
++
++typedef struct s_ReplaceData {
++  QString  dtag;
++  QString  did;
++  QString  dprop;
++  QString  newtag;
++  QString  newprop;
++  QString  newpropval;
++} ReplaceData;
++
++typedef struct s_AddData {
++  QString  dtag;
++  QString  did;
++  QString  newtag;
++  QString  newprop;
++  QString  newpropval;
++} AddData;
++
++bool
++do_walkdoc(QDomNode  n,
++  TraverseCallback  cb,
++  void *            cbdata,
++  QString *errorMessage)
++{
++  QTextStream error(stderr);
++  if ( !n.isNull() ) {
++    if ( n.isElement() ) {
++      QDomElement e = n.toElement();
++      (*cb)(cbdata, e);
++    }
++    if ( n.hasChildNodes() ) {
++      QDomNodeList subnodes = n.childNodes();
++      int i = 0;
++      while (i < subnodes.count()) {
++        do_walkdoc(subnodes.item(i++), cb, cbdata, errorMessage);
++      }
++    }
++  }
++  return true;
++}
++
++bool
++walkdoc(QDomDocument *doc,
++  TraverseCallback  cb,
++  void *            cbdata,
++  QString *errorMessage)
++{
++  QTextStream error(stderr);
++  QDomNode n = doc->documentElement();
++  do_walkdoc(n, cb, cbdata, errorMessage);
++  return true;
++}
++
++void 
++splicefunc(void *cbdata,
++ QDomElement e)
++{
++  SpliceData *d = reinterpret_cast<SpliceData *>(cbdata);
++  QString eid = e.attribute(WIX_ATTR_ID);
++
++  if (e.tagName().compare(d->dtag) == 0) {
++    /* if a specific Id is set, verify it too. */
++    if (d->did.isEmpty() ||
++        (eid.size() && !eid.compare(d->did)) ) {
++
++      /* expected behavior is to graft children of the splice under target.
++       * if we're only given a single element graft it instead.
++       */
++      if (d->splice.hasChildNodes()) {
++        QDomNodeList subnodes = d->splice.childNodes();
++        int i = 0;
++        while (i < subnodes.count()) {
++          e.appendChild(e.ownerDocument().importNode(subnodes.item(i++), true));
++        }
++      }
++      else {
++        e.appendChild(e.ownerDocument().importNode(d->splice, true));
++      }
++    }
++  }
++}
++
++/** Make modifications to requested documents.
++ * returns false on error and <b>errorMessage</b> will be set.
++ */
++bool
++docsplice(QDomDocument *doc,
++  QString arguments,
++  QString *errorMessage)
++{
++  Q_ASSERT(doc);
++  Q_ASSERT(errorMessage);
++  SpliceData  cbdata;
++
++  QStringList spliceinfo = arguments.split("=");
++  if (spliceinfo.count() != 2) {
++    *errorMessage = "Invalid argument for splice command: " + arguments;
++    return false;
++  }
++  if (spliceinfo[0].contains(':')) {
++    /* Id syntax */
++    QStringList destinfo = spliceinfo[0].split(":");
++    cbdata.dtag = destinfo[0];
++    cbdata.did  = destinfo[1];
++  }
++  else {
++    cbdata.dtag = spliceinfo[0];
++  }
++
++  QStringList  srcinfo = spliceinfo[1].split(":");
++  if (srcinfo.count() < 2) {
++    *errorMessage = "Invalid source argument for splice command: " + arguments;
++    return false;
++  }
++  QFile spliceFile(srcinfo[0]);
++  if (!spliceFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
++    *errorMessage = QString("Unable to open '%1' for reading: %2\n")
++                     .arg(srcinfo[0]).arg(spliceFile.errorString());
++    return false;
++  }
++  QTextStream sfiletxt(&spliceFile);
++  QDomDocument sdoc;
++  QString parseError;
++  int  badline, badcol;
++  if (!sdoc.setContent (sfiletxt.readAll(), false, &parseError, &badline, &badcol)) {
++    *errorMessage = QString("Error parsing splice document '%1' at line %2 and column %3: %4")
++                    .arg(srcinfo[0]).arg(badline).arg(badcol).arg(parseError);
++    return false;
++  }
++
++  QDomNodeList elist = sdoc.elementsByTagName(srcinfo[1]);
++  if (elist.count() == 0) {
++    *errorMessage = QString("Unable to locate splice element '%1' in document.\n").arg(srcinfo[1]);
++    return false;
++  }
++  if (srcinfo.count() == 3) {
++    /* Id syntax for source elem */
++    for (int i=0; i < elist.count(); i++) {
++      QString eid = elist.item(i).toElement().attribute(WIX_ATTR_ID);
++      if (eid.size() && !eid.compare(srcinfo[2])) {
++        cbdata.splice = elist.item(i).toElement();
++      }
++    }
++  }
++  else {
++    /* without an Id the tag name should be unique. */
++    cbdata.splice = elist.item(0).toElement();
++  }
++  return walkdoc(doc, &splicefunc, &cbdata, errorMessage);
++}
++
++void 
++replacefunc(void *cbdata,
++ QDomElement e)
++{
++  ReplaceData *d = reinterpret_cast<ReplaceData *>(cbdata);
++  QString eid = e.attribute(WIX_ATTR_ID);
++
++  if (e.tagName().compare(d->dtag) == 0) {
++    /* if a specific Id is set, verify it too. */
++    if (d->did.isEmpty() ||
++        (eid.size() && !eid.compare(d->did)) ) {
++
++      /* no destination means remove node from tree */
++      if (d->newtag.isNull()) {
++        QDomNode parent = e.parentNode();
++        parent.removeChild(e);
++      }
++      else {
++        if (d->newtag.compare(e.tagName())) {
++          e.setTagName (d->newtag);
++        }
++        if (d->newprop.isNull()) {
++          /* clear all attributes (except Id if present) */
++          QDomNamedNodeMap attrs = e.attributes();
++          for (int i = 0; i < attrs.count(); i++) {
++            if (attrs.item(i).nodeName().compare(WIX_ATTR_ID)) {
++              e.removeAttribute(attrs.item(i).nodeName());
++            }
++          }
++        }
++        else {
++          /* only modify / clear a specific property */
++          QDomNode prop = e.attributeNode(d->newprop);
++          if (!prop.isNull()) {
++            e.setAttribute(d->newprop, d->newpropval);
++          }
++        }
++      }
++    }
++  }
++}
++
++/** Make modifications to requested documents.
++ * returns false on error and <b>errorMessage</b> will be set.
++ */
++bool
++docreplace(QDomDocument *doc,
++  QString arguments,
++  QString *errorMessage)
++{
++  Q_ASSERT(doc);
++  Q_ASSERT(errorMessage);
++  ReplaceData  cbdata;
++
++  QStringList replaceinfo = arguments.split("=");
++  if (replaceinfo.count() < 1) {
++    *errorMessage = "Invalid argument for replace command: " + arguments;
++    return false;
++  }
++  if (replaceinfo[0].contains(':')) {
++    /* Id syntax */
++    QStringList destinfo = replaceinfo[0].split(":");
++    cbdata.dtag = destinfo[0];
++    cbdata.did  = destinfo[1];
++    if (destinfo.count() >= 3) {
++      cbdata.dprop = destinfo[2];
++    }
++  }
++  else {
++    cbdata.dtag = replaceinfo[0];
++  }
++  if (replaceinfo.count() > 1) {
++    QStringList  srcinfo = replaceinfo[1].split(":");
++    if (srcinfo.count() < 1) {
++      *errorMessage = "Invalid target argument for replace command: " + arguments;
++      return false;
++    }
++    if (srcinfo.count() >= 1) {
++      if (srcinfo[0].length()) cbdata.newtag = srcinfo[0];
++    }
++    if (srcinfo.count() >= 2) {
++      if (srcinfo[1].length()) cbdata.newprop = srcinfo[1];
++    }
++    if (srcinfo.count() >= 3) {
++      if (srcinfo[2].length()) cbdata.newpropval = srcinfo[2];
++    }
++  }
++  return walkdoc(doc, &replacefunc, &cbdata, errorMessage);
++}
++
++void 
++addfunc(void *cbdata,
++ QDomElement e)
++{
++  AddData *d = reinterpret_cast<AddData *>(cbdata);
++  QString eid = e.attribute(WIX_ATTR_ID);
++
++  if (e.tagName().compare(d->dtag) == 0) {
++    /* if a specific Id is set, verify it too. */
++    if (d->did.isEmpty() ||
++        (eid.size() && !eid.compare(d->did)) ) {
++      if (d->newtag.compare(d->dtag)) {
++        QDomElement ne = e.ownerDocument().createElement(d->newtag);
++        if (!d->newprop.isNull()) {
++          ne.setAttribute(d->newprop, d->newpropval);
++        }
++        e.appendChild(ne);
++      }
++      else {
++        e.setAttribute(d->newprop, d->newpropval);
++      }
++    }
++  }
++}
++
++/** Make modifications to requested documents.
++ * returns false on error and <b>errorMessage</b> will be set.
++ */
++bool
++docadd(QDomDocument *doc,
++  QString arguments,
++  QString *errorMessage)
++{
++  Q_ASSERT(doc);
++  Q_ASSERT(errorMessage);
++  AddData  cbdata;
++
++  QStringList addinfo = arguments.split("=");
++  if (addinfo.count() < 1) {
++    *errorMessage = "Invalid argument for add command: " + arguments;
++    return false;
++  }
++  if (addinfo[0].contains(':')) {
++    /* Id syntax */
++    QStringList destinfo = addinfo[0].split(":");
++    cbdata.dtag = destinfo[0];
++    cbdata.did  = destinfo[1];
++  }
++  else {
++    cbdata.dtag = addinfo[0];
++  }
++  if (addinfo.count() > 1) {
++    QStringList  srcinfo = addinfo[1].split(":");
++    if (srcinfo.count() < 1) {
++      *errorMessage = "Invalid target argument for add command: " + arguments;
++      return false;
++    }
++    if (srcinfo.count() >= 1) {
++      if (srcinfo[0].length()) cbdata.newtag = srcinfo[0];
++    }
++    if (srcinfo.count() >= 2) {
++      if (srcinfo[1].length()) cbdata.newprop = srcinfo[1];
++    }
++    if (srcinfo.count() >= 3) {
++      if (srcinfo[2].length()) cbdata.newpropval = srcinfo[2];
++    }
++  }
++  return walkdoc(doc, &addfunc, &cbdata, errorMessage);
++}
++
++/** Display application usage and exit. */
++void
++print_usage_and_exit()
++{
++  QTextStream error(stderr);
++  error << "usage: wixtool <command> [-q] -i <infile> -o <outfile> <Arg0> ... <ArgN>" << endl;
++  error << "  command one of: " << endl;
++  error << "    splice        Splice children from one document into another." << endl;
++  error << "    replace       Replace elements or attributes in a document." << endl;
++  error << "    add           Add elements or attributes into a document." << endl;
++  error << "    userlocal     Convert File elements into per-user local elements." << endl;
++  error << "  -i <infile>     Input or template file" << endl;
++  error << "  -o <outfile>    Output file" << endl;
++  error << endl;
++  error << "  splice args:    desttagname[:Id]=file:basetag[:Id]" << endl;
++  error << "    Splice children of basetag in file under desttagname" << endl;
++  error << endl;
++  error << "  replace args:   tagname[:Id]:property=newtagname[:Id]:property:value" << endl;
++  error << "    If newtagname is empty the element is deleted" << endl;
++  error << "    If newproperty is empty the property is deleted" << endl;
++  error << endl;
++  error << "  add args:       desttagname[:Id]=newtagname[:Id]:property:value" << endl;
++  error << "    Add properties or child elements to target" << endl;
++  error << "    If newtagname is empty only properties added to dest" << endl;
++  error << endl;
++  error << "  userlocal args: [tagname][:Id]" << endl;
++  error << "    Convert KeyPath File elements into the per user local idiom" << endl;
++  error << "    with corresponding Create/RemoveDir and RegistryKey elements." << endl;
++  error << endl;
++  error << " NOTE: text content within an element is not accessible." << endl;
++  error << "       Use the Value= attribute syntax if necessary." << endl;
++  error << "       The optional :Id syntax restricts matching to elements with" << endl;
++  error << "       the Id attribute set to the value indicated." << endl;
++  error.flush();
++  exit(1);
++}
++
++int
++main(int argc, char *argv[])
++{
++  QTextStream error(stderr);
++  QString command, errorMessage;
++  char *infile = 0, *outfile = 0;
++  QTextCodec *codec = QTextCodec::codecForName("utf-8");
++  bool quiet = false;
++  QStringList commandargs;
++
++  /* Check for the correct number of input parameters. */
++  if (argc < 6)
++    print_usage_and_exit();
++
++  /* Verify command is supported. */
++  command = argv[1];
++  if ( command.compare("splice", Qt::CaseInsensitive) &&
++       command.compare("replace", Qt::CaseInsensitive) &&
++       command.compare("add", Qt::CaseInsensitive) ) {
++    print_usage_and_exit();
++  }
++
++  /* Gather remaining arguments. */
++  for (int i = 2; i < argc; i++) {
++    QString arg(argv[i]);
++    if (!arg.compare("-q", Qt::CaseInsensitive))
++      quiet = true;
++    else if (!arg.compare("-i", Qt::CaseInsensitive) && ++i < argc)
++      infile = argv[i];
++    else if (!arg.compare("-o", Qt::CaseInsensitive) && ++i < argc)
++      outfile = argv[i];
++    else if (infile && outfile) {
++      commandargs.append(arg);
++    }
++  }
++  if ( !infile || !outfile || !commandargs.count() ) {
++    print_usage_and_exit();
++  }
++
++  /* Open the source document for reading. */
++  QFile srcFile(infile);
++  QTextStream sfiletxt(&srcFile);
++  sfiletxt.setCodec(codec);
++  if (!srcFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
++    error << QString("Unable to open '%1' for reading: %2\n").arg(infile)
++                                                .arg(srcFile.errorString());
++    return 2;
++  }
++
++  QDomDocument doc;
++  QString parseError;
++  int  badline, badcol;
++  if (!doc.setContent (sfiletxt.readAll(), false, &parseError, &badline, &badcol)) {
++    error << QString("Error parsing source document '%1' at line %2 and column %3: %4")
++                    .arg(infile).arg(badline).arg(badcol).arg(parseError);
++    return 3;
++  }
++
++  for (int i = 0; i < commandargs.count(); i++) {
++    if (!command.compare("splice", Qt::CaseInsensitive)) {
++      if (!docsplice(&doc, commandargs[i], &errorMessage)) {
++        error << QString("Unable to process splice command '%1': %2\n")
++                        .arg(commandargs[i]).arg(errorMessage);
++        return 4;
++      }
++    }
++    else if (!command.compare("replace", Qt::CaseInsensitive)) {
++        return 4;
++    }
++    else if (!command.compare("add", Qt::CaseInsensitive)) {
++        return 4;
++    }
++  }
++
++  /* Open the output file for writing. */
++  QFile docFile(outfile);
++  if (!docFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
++    error << QString("Unable to open '%1' for writing: %2\n").arg(outfile)
++                                                .arg(docFile.errorString());
++    return 5;
++  }
++
++  /* Write the .wxl output. */
++  QTextStream out(&docFile);
++  out << doc.toString(4);
++
++  return 0;
++}
++
 diff -Naur a/src/vidalia/config/torsettings.cpp b/src/vidalia/config/torsettings.cpp
 --- a/src/vidalia/config/torsettings.cpp	2009-01-30 05:20:24.536180000 +0000
-+++ b/src/vidalia/config/torsettings.cpp	2009-03-01 00:53:58.322690336 +0000
++++ b/src/vidalia/config/torsettings.cpp	2009-03-07 03:57:41.693104376 +0000
 @@ -61,6 +61,7 @@
  {
  #if defined(Q_OS_WIN32)
@@ -684,7 +1286,7 @@
    setDefault(SETTING_AUTH_METHOD,   toString(DEFAULT_AUTH_METHOD));
 diff -Naur a/src/vidalia/config/vidaliasettings.cpp b/src/vidalia/config/vidaliasettings.cpp
 --- a/src/vidalia/config/vidaliasettings.cpp	2009-02-03 02:09:39.844750000 +0000
-+++ b/src/vidalia/config/vidaliasettings.cpp	2009-03-01 00:53:58.323690184 +0000
++++ b/src/vidalia/config/vidaliasettings.cpp	2009-03-07 03:57:41.694104224 +0000
 @@ -71,9 +71,16 @@
    setDefault(SETTING_SHOW_MAINWINDOW_AT_START, true);
    setDefault(SETTING_BROWSER_EXECUTABLE, "");
@@ -707,7 +1309,7 @@
  #else
 diff -Naur a/src/vidalia/network/geoipresolver.cpp b/src/vidalia/network/geoipresolver.cpp
 --- a/src/vidalia/network/geoipresolver.cpp	2008-12-30 18:48:55.745877000 +0000
-+++ b/src/vidalia/network/geoipresolver.cpp	2009-03-01 00:53:58.324690032 +0000
++++ b/src/vidalia/network/geoipresolver.cpp	2009-03-07 03:57:41.694104224 +0000
 @@ -24,13 +24,13 @@
  #endif
  
@@ -742,7 +1344,7 @@
  }
 diff -Naur a/src/vidalia/network/tormapwidget.cpp b/src/vidalia/network/tormapwidget.cpp
 --- a/src/vidalia/network/tormapwidget.cpp	2009-02-19 21:15:24.029490000 +0000
-+++ b/src/vidalia/network/tormapwidget.cpp	2009-03-01 00:53:58.324690032 +0000
++++ b/src/vidalia/network/tormapwidget.cpp	2009-03-07 03:57:41.695104072 +0000
 @@ -24,8 +24,8 @@
  using namespace Marble;
  
@@ -769,7 +1371,7 @@
    TorMapWidgetPopupMenu *popupMenu  = new TorMapWidgetPopupMenu(this);
 diff -Naur a/src/vidalia/res/entrust-secure-server-root.crt b/src/vidalia/res/entrust-secure-server-root.crt
 --- a/src/vidalia/res/entrust-secure-server-root.crt	1970-01-01 00:00:00.000000000 +0000
-+++ b/src/vidalia/res/entrust-secure-server-root.crt	2009-03-01 00:53:58.324690032 +0000
++++ b/src/vidalia/res/entrust-secure-server-root.crt	2009-03-07 03:57:41.695104072 +0000
 @@ -0,0 +1,30 @@
 +-----BEGIN CERTIFICATE-----
 +MIIE2DCCBEGgAwIBAgIEN0rSQzANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UE
@@ -803,7 +1405,7 @@
 +-----END CERTIFICATE-----
 diff -Naur a/src/vidalia/res/gd-class2-root.crt b/src/vidalia/res/gd-class2-root.crt
 --- a/src/vidalia/res/gd-class2-root.crt	1970-01-01 00:00:00.000000000 +0000
-+++ b/src/vidalia/res/gd-class2-root.crt	2009-03-01 00:53:58.325689880 +0000
++++ b/src/vidalia/res/gd-class2-root.crt	2009-03-07 03:57:41.696103920 +0000
 @@ -0,0 +1,24 @@
 +-----BEGIN CERTIFICATE-----
 +MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh
@@ -831,7 +1433,7 @@
 +-----END CERTIFICATE-----
 diff -Naur a/src/vidalia/res/vidalia.qrc b/src/vidalia/res/vidalia.qrc
 --- a/src/vidalia/res/vidalia.qrc	2009-02-01 00:34:33.066938000 +0000
-+++ b/src/vidalia/res/vidalia.qrc	2009-03-01 00:53:58.325689880 +0000
++++ b/src/vidalia/res/vidalia.qrc	2009-03-07 03:57:41.696103920 +0000
 @@ -290,5 +290,7 @@
      </qresource>
      <qresource prefix="/geoip">
@@ -842,7 +1444,7 @@
  </RCC>
 diff -Naur a/src/vidalia/updateprocess.cpp b/src/vidalia/updateprocess.cpp
 --- a/src/vidalia/updateprocess.cpp	2009-01-03 20:10:16.806554000 +0000
-+++ b/src/vidalia/updateprocess.cpp	2009-03-01 00:53:58.326689728 +0000
++++ b/src/vidalia/updateprocess.cpp	2009-03-07 03:57:41.698103616 +0000
 @@ -234,13 +234,23 @@
  QString
  UpdateProcess::updateExecutable()
@@ -870,7 +1472,7 @@
  QString
 diff -Naur a/src/vidalia/vidalia.cpp b/src/vidalia/vidalia.cpp
 --- a/src/vidalia/vidalia.cpp	2009-02-24 04:56:35.504853000 +0000
-+++ b/src/vidalia/vidalia.cpp	2009-03-01 00:53:58.327689576 +0000
++++ b/src/vidalia/vidalia.cpp	2009-03-07 03:57:41.699103464 +0000
 @@ -89,6 +89,11 @@
  Vidalia::Vidalia(QStringList args, int &argc, char **argv)
  : QApplication(argc, argv)

Added: torvm/trunk/build/win32/src/pkg/license.wxs
===================================================================
--- torvm/trunk/build/win32/src/pkg/license.wxs	                        (rev 0)
+++ torvm/trunk/build/win32/src/pkg/license.wxs	2009-03-07 15:52:50 UTC (rev 18796)
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="Windows-1252" ?>
+<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi";>
+  <?define ThisProductVersion="0.0.2" ?>
+  <?define ThisProductVersionDisp="0.0.2" ?>
+  <?define UpgradeCode="bda6a744-0815-4fdc-88a8-d40d8c154133" ?>
+  <?define CurrProductGUID="43b6b534-8148-4813-8d22-4da1df4783c3" ?>
+  <?define CurrDocsOnDesktopGUID="d20d7258-1e4a-4d26-a2f4-e08a939a0ae8" ?>
+
+  <Product Name="Tor Vidalia Bundle License Docs $(var.ThisProductVersionDisp)" Id="$(var.CurrProductGUID)"
+           Language="!(loc.LCID)"
+           Version="$(var.ThisProductVersion)"
+           Manufacturer="www.torproject.org"
+           UpgradeCode="$(var.UpgradeCode)">
+    
+    <Package Id="*" Keywords="Installer"
+             Description="Tor Vidalia Bundle License Docs $(var.ThisProductVersionDisp) Installer"
+             Manufacturer="www.torproject.org"
+             InstallerVersion="200" Compressed="yes"
+             InstallPrivileges="limited" />
+
+    <Media Id="1" Cabinet="License.cab" CompressionLevel="high"
+           EmbedCab="yes" DiskPrompt="CD-ROM #1" />
+    <Property Id="DiskPrompt" Value="Tor Vidalia Bundle License Docs $(var.ThisProductVersionDisp) Installation Volume [1]" />
+    <Property Id="ALLUSERS" Secure="yes"/>
+    <Property Id="ReinstallModeText">omus</Property>
+
+    <!-- Associate this package with the upgrade code for this series
+    to ensure that upgrade installations by Thandy or other means work
+    as expected.
+    The OnlyDetect option must be false to ensure that existing files
+    from an older version are removed and replaced with current files.
+      -->
+    <Upgrade Id="$(var.UpgradeCode)">
+      <UpgradeVersion
+        Property="UPGRADEFOUND"
+        OnlyDetect="no"
+        Minimum="0.0.1"
+        IncludeMinimum="yes"
+        Maximum="$(var.ThisProductVersion)"
+        IncludeMaximum="no"
+      />
+    </Upgrade>
+
+
+    <Directory Id="TARGETDIR" Name="SourceDir">
+      <Directory Id="ProgramFilesFolder" Name="ProgramFiles">
+        <Directory Id="ProgramsInstDir" Name="Tor Vidalia License Docs">
+        </Directory>
+      </Directory>
+      <Directory Id="DesktopFolder" Name="Desktop">
+        <Component Id="AddTorDocsToDesktop" Guid="$(var.CurrDesktopGUID)">
+          <RegistryKey Root="HKCU" Key="Software\Tor Vidalia License Docs" Action="createAndRemoveOnUninstall">
+            <RegistryValue Name="DesktopShortcut" Value="1" Type="integer" KeyPath="yes" />
+          </RegistryKey>
+          <Shortcut Id="TorDocsDesktopShortcut"
+                    Name="Tor Vidalia License Docs" Target="[ProgramsInstDir]"
+                    Directory="DesktopFolder" WorkingDirectory="ProgramsInstDir" />
+        </Component>
+      </Directory>
+    </Directory>
+
+    <!-- Build up the feature hierarchy -->
+    <Feature Id="Complete" Title="Tor Vidalia License Docs"
+             Level="1" Display="expand"
+             Description="" />
+      <Feature Id="MainApplication" Title="Tor Vidalia License Docs $(var.ThisProductVersionDisp)"
+               AllowAdvertise="no" Absent="disallow" Level="1"
+               Description="Main application">
+        <ComponentRef Id="DocFolder" />
+      </Feature>
+      <Feature Id="Shortcuts" Title="Shortcuts"
+               AllowAdvertise="no" Absent="allow" Level="1"
+               Description="Add a shortcut to Desktop.">
+        <Feature Id="DesktopShortcuts" Title="Add to Desktop"
+                 AllowAdvertise="no" Absent="allow" Level="1"
+                 Description="Add Tor Docs to your Desktop">
+          <ComponentRef Id="AddTorDocsToDesktop" />
+        </Feature>
+      </Feature>
+    </Feature>
+
+    <!-- Upgrade installation sequence. -->
+    <InstallExecuteSequence>
+      <RemoveExistingProducts After="InstallValidate" />
+    </InstallExecuteSequence>
+
+    <!-- Set the UI options -->
+    <UIRef Id="WixUI_Custom" />
+    <Icon Id="tor.ico" SourceFile="tor.ico" />
+    <WixVariable Id="WixUIBannerBmp" Value="header.bmp" />
+    <WixVariable Id="WixUIDialogBmp" Value="welcome.bmp" />
+  </Product>
+</Wix>