tRemove old Windows installer - vaccinewars - be a doctor and try to vaccinate the world
 (HTM) git clone git://src.adamsgaard.dk/vaccinewars
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit c35ba28b21ec5a92791d0c3c3ae10180df2b4851
 (DIR) parent e02dae44581855d88b21163f0ad6e6c72e7d162a
 (HTM) Author: Ben Webb <ben@salilab.org>
       Date:   Tue,  1 Dec 2020 21:12:12 -0800
       
       Remove old Windows installer
       
       Diffstat:
         D win32/Makefile                      |      58 ------------------------------
         M win32/README.md                     |      12 +++---------
         D win32/bzlib/Makefile.nocygwin       |      33 -------------------------------
         D win32/bzlib/README.bzlib            |       7 -------
         D win32/contid.h                      |      18 ------------------
         D win32/dialogs.rc                    |      75 -------------------------------
         D win32/filelist                      |     108 -------------------------------
         D win32/guifunc.c                     |     103 -------------------------------
         D win32/guifunc.h                     |      26 --------------------------
         D win32/makeinstall.c                 |     353 -------------------------------
         D win32/setup.c                       |    1242 ------------------------------
         D win32/setup.ico                     |       0 
         D win32/setup.manifest                |      21 ---------------------
         D win32/setup.rc                      |       8 --------
         D win32/uninstall.c                   |     196 -------------------------------
         D win32/uninstall.manifest            |      21 ---------------------
         D win32/uninstall.rc                  |      16 ----------------
         D win32/util.c                        |     896 -------------------------------
         D win32/util.h                        |     119 -------------------------------
         D win32/zlib/Makefile.nocygwin        |     154 -------------------------------
         D win32/zlib/README.zlib              |       6 ------
       
       21 files changed, 3 insertions(+), 3469 deletions(-)
       ---
 (DIR) diff --git a/win32/Makefile b/win32/Makefile
       t@@ -1,58 +0,0 @@
       -# Use these flags to use libbz2 for compression
       -#LIBZ      = bzlib/libbz2.a
       -#COMPFLAGS = -DLIBBZ2
       -
       -# Use these flags to use libz for compression
       -LIBZ      = zlib/libz.a
       -COMPFLAGS =
       -
       -CFLAGS = -Wall -mno-cygwin ${COMPFLAGS}
       -
       -all: setup makeinstall uninstall
       -
       -clean:
       -        /bin/rm -f *.o *.res uninstall.exe setup.exe makeinstall.exe core *~
       -        /bin/rm -f installfiles.z manifest
       -
       -setup: setup.o util.o guifunc.o setup.res
       -        gcc ${CFLAGS} -mwindows -o setup setup.o util.o guifunc.o setup.res ${LIBZ} -lcomctl32 -lole32 -luuid
       -        strip setup.exe
       -
       -uninstall: uninstall.o util.o guifunc.o uninstall.res
       -        gcc ${CFLAGS} -mwindows -o uninstall uninstall.o util.o guifunc.o uninstall.res 
       -        strip uninstall.exe
       -
       -uninstall.o: uninstall.c util.h guifunc.h
       -        gcc ${CFLAGS} -c uninstall.c
       -
       -uninstall.res: uninstall.rc
       -        windres -O coff -o uninstall.res uninstall.rc
       -
       -setup.o: setup.c contid.h util.h guifunc.h
       -        gcc ${CFLAGS} -c setup.c
       -
       -util.o: util.c util.h
       -        gcc ${CFLAGS} -c util.c
       -
       -guifunc.o: guifunc.c guifunc.h
       -        gcc ${CFLAGS} -c guifunc.c
       -
       -manifest installfiles.z: filelist makeinstall uninstall
       -        sed -e 's/LICENCE/licence.txt/' < ../doc/index.html > index.html
       -        sed -e 's/LICENCE/licence.txt/' < ../doc/developer.html > developer.html
       -        sed -e 's/example-cfg/example-cfg.txt/' < ../doc/configfile.html > configfile.html
       -        awk '{gsub(/\f/, ""); print $$0."\r"}' < ../LICENCE > licence.txt
       -        awk '{print $$0."\r"}' < ../README > readme.txt
       -        awk '{print $$0."\r"}' < ../doc/example-cfg > example-cfg.txt
       -        ./makeinstall
       -        /bin/rm -f index.html configfile.html developer.html licence.txt
       -        /bin/rm -f example-cfg.txt readme.txt
       -
       -setup.res: setup.rc dialogs.rc contid.h manifest installfiles.z
       -        windres -O coff -o setup.res setup.rc
       -
       -makeinstall: makeinstall.o util.o
       -        gcc ${CFLAGS} -o makeinstall makeinstall.o util.o ${LIBZ}
       -
       -makeinstall.o: makeinstall.c util.h
       -        gcc ${CFLAGS} -c makeinstall.c
 (DIR) diff --git a/win32/README.md b/win32/README.md
       t@@ -1,7 +1,5 @@
        ## Building dopewars on Windows
        
       -(This is experimental.)
       -
        dopewars is built for Windows via cross-compilation on Linux using the
        MinGW tools. See the `mingw` subdirectory for a suitable `Dockerfile` to set up
        a [Docker](https://www.docker.com/) or [Podman](https://podman.io/)
       t@@ -22,10 +20,6 @@ the same directory as `dopewars.exe`.
        
        ## Windows installer
        
       -This directory contains the code for a simple Windows install/uninstall
       -package. The `makeinstall` program takes a list of files (in `filelist`) to
       -install, and produces a compressed copy of these files, which are placed
       -into the resources of the `setup` program. This program installs the listed
       -files to a target machine, and sets up the necessary registry keys for the
       -`uninstall` program to then be able to remove those files again. The only
       -file that should need to be distributed, therefore, is `setup.exe`.
       +The top-level `configure` script will also generate `install.nsi` in this
       +directory. This can be used as input to
       +[NSIS](https://nsis.sourceforge.io/) to build a Windows installer.
 (DIR) diff --git a/win32/bzlib/Makefile.nocygwin b/win32/bzlib/Makefile.nocygwin
       t@@ -1,33 +0,0 @@
       -
       -SHELL=/bin/sh
       -
       -# To assist in cross-compiling
       -CC=gcc
       -AR=ar
       -RANLIB=ranlib
       -LDFLAGS=
       -
       -# Suitably paranoid flags to avoid bugs in gcc-2.7
       -BIGFILES=-D_FILE_OFFSET_BITS=64
       -CFLAGS=-mno-cygwin -Wall -Winline -O2 -fomit-frame-pointer -fno-strength-reduce -DBZ_NO_STDIO $(BIGFILES)
       -
       -# Where you want it installed when you do 'make install'
       -PREFIX=/usr
       -
       -
       -OBJS= blocksort.o  \
       -      huffman.o    \
       -      crctable.o   \
       -      randtable.o  \
       -      compress.o   \
       -      decompress.o \
       -      bzlib.o
       -
       -libbz2.a: $(OBJS)
       -        rm -f libbz2.a
       -        $(AR) cq libbz2.a $(OBJS)
       -        @if ( test -f $(RANLIB) -o -f /usr/bin/ranlib -o \
       -                -f /bin/ranlib -o -f /usr/ccs/bin/ranlib ) ; then \
       -                echo $(RANLIB) libbz2.a ; \
       -                $(RANLIB) libbz2.a ; \
       -        fi
 (DIR) diff --git a/win32/bzlib/README.bzlib b/win32/bzlib/README.bzlib
       t@@ -1,7 +0,0 @@
       -If you are intending to build the Win32 installer for dopewars, then place
       -the bzlib distribution (from http://sources.redhat.com/bzip2/) into this
       -directory. The installer expects to statically link with the file libbz2.a
       -in this directory; the libbz2.a file included in the Cygwin distribution
       -should _not_ be used, as this requires the CYGWIN.DLL file, which is not
       -a standard Windows DLL. Use the Makefile.nocygwin file to compile bzlib,
       -as this adds in the -mno-cygwin flag.
 (DIR) diff --git a/win32/contid.h b/win32/contid.h
       t@@ -1,18 +0,0 @@
       -#define BT_BACK     201
       -#define BT_NEXT     202
       -#define BT_CANCEL   203
       -#define BT_FINISH   204
       -#define BT_BROWSE   205
       -#define ED_LICENCE  206
       -#define ST_FILELIST 207
       -#define ST_COMPLETE 208
       -#define ST_EXIT     209
       -#define ED_FOLDER   210
       -#define LB_FOLDLIST 211
       -#define CB_DESKTOP  212
       -#define ED_INSTDIR  213
       -#define ST_DELSTAT  214
       -#define ST_DELDONE  215
       -#define BT_DELOK    216
       -#define RB_ALLUSERS 217
       -#define RB_ONEUSER  218
 (DIR) diff --git a/win32/dialogs.rc b/win32/dialogs.rc
       t@@ -1,75 +0,0 @@
       -#include "contid.h"
       -1 DIALOG 17, 40, 239, 162
       -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
       -CAPTION "dopewars-1.5.12 installation"
       -BEGIN
       -        CONTROL "", 101, "WC_GTKSEP", 2 | WS_CHILD | WS_VISIBLE, 7, 135, 225, 2
       -        CONTROL "< &Back", BT_BACK, "BUTTON", BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_DISABLED | WS_TABSTOP, 105, 143, 39, 13
       -        PUSHBUTTON "&Next >", BT_NEXT, 144, 143, 39, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP
       -        PUSHBUTTON "&Cancel", BT_CANCEL, 191, 143, 39, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP
       -        LTEXT "Welcome to the dopewars-1.5.12 installation program.\nThis program will install dopewars-1.5.12 on your computer.", -1, 22, 14, 195, 17, WS_CHILD | WS_VISIBLE | WS_GROUP
       -        LTEXT "Use the ""Back"" and ""Next"" buttons at the bottom of the dialog to control the installation. You can quit at any time using the ""Cancel"" button.", -1, 22, 50, 195, 25, WS_CHILD | WS_VISIBLE | WS_GROUP
       -        LTEXT "Newer versions of this program, when available, can be obtained from the dopewars website, http://dopewars.sf.net/", -1, 22, 84, 195, 18, WS_CHILD | WS_VISIBLE | WS_GROUP
       -        CONTROL "Install for &all users (requires admin rights)", RB_ALLUSERS, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 28, 108, 110, 8
       -        CONTROL "Install for c&urrent user only", RB_ONEUSER, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 28, 120, 108, 8
       -END
       -2 DIALOG 17, 40, 239, 162
       -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
       -CAPTION "License"
       -BEGIN
       -        CONTROL "", 101, "WC_GTKSEP", 2 | WS_CHILD | WS_VISIBLE, 7, 135, 225, 2
       -        PUSHBUTTON "< &Back", BT_BACK, 105, 143, 39, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP
       -        PUSHBUTTON "&Next >", BT_NEXT, 144, 143, 39, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP
       -        PUSHBUTTON "&Cancel", BT_CANCEL, 191, 143, 39, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP
       -        LTEXT "dopewars is released under the terms of the GNU General Public License (GPL). Please take a moment to review the terms of this license before continuing.", -1, 22, 14, 195, 25, WS_CHILD | WS_VISIBLE | WS_GROUP
       -        CONTROL "", ED_LICENCE, "EDIT", ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP | WS_VSCROLL, 22, 45, 195, 75
       -END
       -
       -4 DIALOG 17, 40, 239, 162
       -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
       -CAPTION "Installation directory"
       -BEGIN
       -        CONTROL "", 101, "WC_GTKSEP", 2 | WS_CHILD | WS_VISIBLE, 7, 135, 225, 2
       -        PUSHBUTTON "< &Back", BT_BACK, 105, 143, 39, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP
       -        PUSHBUTTON "&Next >", BT_NEXT, 144, 143, 39, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP
       -        PUSHBUTTON "&Cancel", BT_CANCEL, 191, 143, 39, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP
       -        LTEXT "dopewars will be installed into the directory given below.", -1, 22, 14, 195, 9, WS_CHILD | WS_VISIBLE | WS_GROUP
       -        LTEXT "To install in this directory, select ""Next"".", -1, 22, 33, 195, 9, WS_CHILD | WS_VISIBLE | WS_GROUP
       -        LTEXT "To install in a different directory, enter the new directory into the box below, using the ""Browse"" button if necessary.", -1, 22, 51, 195, 35, WS_CHILD | WS_VISIBLE | WS_GROUP
       -        GROUPBOX "Destination directory", 105, 22, 84, 195, 35, WS_CHILD | WS_VISIBLE | WS_TABSTOP
       -        CONTROL "", ED_INSTDIR, "EDIT", ES_LEFT | ES_AUTOHSCROLL | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 27, 99, 142, 10
       -        PUSHBUTTON "B&rowse...", BT_BROWSE, 173, 98, 39, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP
       -END
       -
       -
       -5 DIALOG 17, 40, 239, 162
       -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
       -CAPTION "Installing..."
       -BEGIN
       -        CONTROL "", 101, "WC_GTKSEP", 2 | WS_CHILD | WS_VISIBLE, 7, 135, 225, 2
       -        CONTROL "< &Back", BT_BACK, "BUTTON", BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_DISABLED | WS_TABSTOP, 105, 143, 39, 13
       -        PUSHBUTTON "&Finish", BT_FINISH, 144, 143, 39, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP
       -        CONTROL "&Cancel", BT_CANCEL, "BUTTON", BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_DISABLED | WS_TABSTOP, 191, 143, 39, 13
       -        LTEXT "Please wait while all program files are installed.", -1, 22, 14, 195, 12, WS_CHILD | WS_VISIBLE | WS_GROUP
       -        LTEXT "Installing file:", ST_FILELIST, 22, 38, 195, 16, WS_CHILD | WS_VISIBLE | WS_GROUP
       -        LTEXT "dopewars installation is complete. Click the ""Finish"" button to leave the installation program.", ST_COMPLETE, 22, 63, 195, 18, WS_CHILD | WS_GROUP
       -        LTEXT "Don't forget to check the dopewars website, http://dopewars.sf.net/, for further information and for newer versions of this software. Hope you enjoy the game!", ST_EXIT, 22, 92, 195, 26, WS_CHILD | WS_GROUP
       -END
       -
       -mainicon ICON "setup.ico"
       -
       -3 DIALOG 17, 40, 239, 162
       -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
       -CAPTION "Shortcuts"
       -BEGIN
       -        LTEXT "Program icons will be added to the Program Folder on the Start Menu shown below. You can enter a new folder name, or select one from the Existing Folders list.", -1, 22, 7, 195, 25, WS_CHILD | WS_VISIBLE | WS_GROUP
       -        LTEXT "&Program Folder:", -1, 22, 35, 68, 8, WS_CHILD | WS_VISIBLE | WS_GROUP
       -        CONTROL "", ED_FOLDER, "EDIT", ES_LEFT | ES_AUTOHSCROLL | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 22, 45, 195, 10
       -        LTEXT "E&xisting Folders:", -1, 22, 61, 92, 8, WS_CHILD | WS_VISIBLE | WS_GROUP
       -        CONTROL "", LB_FOLDLIST, "LISTBOX", LBS_NOTIFY | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL | WS_TABSTOP, 22, 71, 195, 46
       -        CONTROL "C&reate desktop icons as well", CB_DESKTOP, "BUTTON", BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 22, 121, 110, 10
       -        CONTROL "", 101, "WC_GTKSEP", 2 | WS_CHILD | WS_VISIBLE, 7, 135, 225, 2
       -        PUSHBUTTON "< &Back", BT_BACK, 105, 143, 39, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP
       -        PUSHBUTTON "&Next >", BT_NEXT, 144, 143, 39, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP
       -        PUSHBUTTON "&Cancel", BT_CANCEL, 191, 143, 39, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP
       -END
 (DIR) diff --git a/win32/filelist b/win32/filelist
       t@@ -1,108 +0,0 @@
       -[product]
       -dopewars-1.5.12
       -
       -[instdir]
       -dopewars-1.5.12
       -
       -[NT Service]
       -dopewars-server
       -dopewars server
       -Server for the drug-dealing game "dopewars"
       -dopewars.exe -N
       -
       -[install]
       -licence.txt
       -uninstall.exe
       -../doc/aiplayer.html -> aiplayer.html
       -../doc/clientplay.html -> clientplay.html
       -../doc/commandline.html -> commandline.html
       -../doc/contribute.html -> contribute.html
       -configfile.html
       -../doc/credits.html -> credits.html
       -developer.html
       -../doc/i18n.html -> i18n.html
       -index.html
       -../doc/installation.html -> installation.html
       -../doc/metaserver.html -> metaserver.html
       -../doc/protocol.html -> protocol.html
       -../doc/server.html -> server.html
       -../doc/servercommands.html -> servercommands.html
       -../doc/windows.html -> windows.html
       -../doc/help/general.html -> help\general.html
       -../doc/help/locations.html -> help\locations.html
       -../doc/help/drugs.html -> help\drugs.html
       -../doc/help/guns.html -> help\guns.html
       -../doc/help/cops.html -> help\cops.html
       -../doc/help/server.html -> help\server.html
       -../doc/help/sounds.html -> help\sounds.html
       -../../auxdope/dopewars-config.txt -> dopewars-config.txt
       -../src/dopewars.exe -> dopewars.exe
       -../../auxdope/iconv.dll -> iconv.dll
       -../../auxdope/intl.dll -> intl.dll
       -../../auxdope/libglib-2.0-0.dll -> libglib-2.0-0.dll
       -readme.txt
       -example-cfg.txt
       -../po/pt_BR.gmo -> locale\pt_BR\LC_MESSAGES\dopewars.mo
       -../po/fr.gmo -> locale\fr\LC_MESSAGES\dopewars.mo
       -../po/de.gmo -> locale\de\LC_MESSAGES\dopewars.mo
       -../po/pl.gmo -> locale\pl\LC_MESSAGES\dopewars.mo
       -../po/nn.gmo -> locale\nn\LC_MESSAGES\dopewars.mo
       -../po/es.gmo -> locale\es\LC_MESSAGES\dopewars.mo
       -../sounds/19.5degs/bye.wav -> sounds\19.5degs\bye.wav
       -../sounds/19.5degs/colt.wav -> sounds\19.5degs\colt.wav
       -../sounds/19.5degs/die.wav -> sounds\19.5degs\die.wav
       -../sounds/19.5degs/gun.wav -> sounds\19.5degs\gun.wav
       -../sounds/19.5degs/jet.wav -> sounds\19.5degs\jet.wav
       -../sounds/19.5degs/losebitch.wav -> sounds\19.5degs\losebitch.wav
       -../sounds/19.5degs/message.wav -> sounds\19.5degs\message.wav
       -../sounds/19.5degs/murmur.wav -> sounds\19.5degs\murmur.wav
       -../sounds/19.5degs/punch.wav -> sounds\19.5degs\punch.wav
       -../sounds/19.5degs/run.wav -> sounds\19.5degs\run.wav
       -../sounds/19.5degs/shotdown.wav -> sounds\19.5degs\shotdown.wav
       -../sounds/19.5degs/train.wav -> sounds\19.5degs\train.wav
       -
       -[extrafiles]
       -dopewars-log.txt
       -dopewars.sco
       -
       -[keepfiles]
       -dopewars-config.txt
       -dopewars-log.txt
       -dopewars.sco
       -
       -[startmenudir]
       -dopewars-1.5.12
       -
       -[startmenu]
       -dopewars.lnk
       -dopewars.exe
       -
       -dopewars server.lnk
       -dopewars.exe
       --s
       -text-mode dopewars.lnk
       -dopewars.exe
       --t
       -dopewars AI player.lnk
       -dopewars.exe
       --c
       -dopewars command line options.lnk
       -dopewars.exe
       --h
       -dopewars help.lnk
       -index.html
       -
       -dopewars configuration file.lnk
       -dopewars-config.txt
       -
       -dopewars example config.lnk
       -example-cfg.txt
       -
       -
       -[desktop]
       -dopewars.lnk
       -dopewars.exe
       -
       -dopewars server.lnk
       -dopewars.exe
       --s
 (DIR) diff --git a/win32/guifunc.c b/win32/guifunc.c
       t@@ -1,103 +0,0 @@
       -/************************************************************************
       - * guifunc.c      GUI-specific shared functions for installer           *
       - * Copyright (C)  2001-2004  Ben Webb                                   *
       - *                Email: benwebb@users.sf.net                           *
       - *                WWW: https://dopewars.sourceforge.io/                 *
       - *                                                                      *
       - * This program is free software; you can redistribute it and/or        *
       - * modify it under the terms of the GNU General Public License          *
       - * as published by the Free Software Foundation; either version 2       *
       - * of the License, or (at your option) any later version.               *
       - *                                                                      *
       - * This program is distributed in the hope that it will be useful,      *
       - * but WITHOUT ANY WARRANTY; without even the implied warranty of       *
       - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        *
       - * GNU General Public License for more details.                         *
       - *                                                                      *
       - * You should have received a copy of the GNU General Public License    *
       - * along with this program; if not, write to the Free Software          *
       - * Foundation, Inc., 59 Temple Place - Suite 330, Boston,               *
       - *                   MA  02111-1307, USA.                               *
       - ************************************************************************/
       -
       -#include <windows.h>
       -#include "guifunc.h"
       -
       -static LRESULT CALLBACK GtkSepProc(HWND hwnd, UINT msg, WPARAM wParam,
       -                                   LPARAM lParam)
       -{
       -  PAINTSTRUCT ps;
       -  HPEN oldpen, dkpen, ltpen;
       -  RECT rect;
       -  HDC hDC;
       -
       -  if (msg == WM_PAINT) {
       -    if (GetUpdateRect(hwnd, NULL, TRUE)) {
       -      BeginPaint(hwnd, &ps);
       -      GetClientRect(hwnd, &rect);
       -      hDC = ps.hdc;
       -      ltpen = CreatePen(PS_SOLID, 0, (COLORREF)GetSysColor(COLOR_3DHILIGHT));
       -      dkpen = CreatePen(PS_SOLID, 0, (COLORREF)GetSysColor(COLOR_3DSHADOW));
       -
       -      if (rect.right > rect.bottom) {
       -        oldpen = SelectObject(hDC, dkpen);
       -        MoveToEx(hDC, rect.left, rect.top, NULL);
       -        LineTo(hDC, rect.right, rect.top);
       -
       -        SelectObject(hDC, ltpen);
       -        MoveToEx(hDC, rect.left, rect.top + 1, NULL);
       -        LineTo(hDC, rect.right, rect.top + 1);
       -      } else {
       -        oldpen = SelectObject(hDC, dkpen);
       -        MoveToEx(hDC, rect.left, rect.top, NULL);
       -        LineTo(hDC, rect.left, rect.bottom);
       -
       -        SelectObject(hDC, ltpen);
       -        MoveToEx(hDC, rect.left + 1, rect.top, NULL);
       -        LineTo(hDC, rect.left + 1, rect.bottom);
       -      }
       -
       -      SelectObject(hDC, oldpen);
       -      DeleteObject(ltpen);
       -      DeleteObject(dkpen);
       -      EndPaint(hwnd, &ps);
       -    }
       -    return TRUE;
       -  } else
       -    return DefWindowProc(hwnd, msg, wParam, lParam);
       -}
       -
       -void RegisterSepClass(HINSTANCE hInstance)
       -{
       -  WNDCLASS wc;
       -
       -  wc.style         = CS_HREDRAW | CS_VREDRAW;
       -  wc.lpfnWndProc   = GtkSepProc;
       -  wc.cbClsExtra    = 0;
       -  wc.cbWndExtra    = 0;
       -  wc.hInstance     = hInstance;
       -  wc.hIcon         = NULL;
       -  wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
       -  wc.hbrBackground = (HBRUSH)(1 + COLOR_BTNFACE);
       -  wc.lpszMenuName  = NULL;
       -  wc.lpszClassName = "WC_GTKSEP";
       -  RegisterClass(&wc);
       -}
       -
       -static BOOL CALLBACK enumFunc(HWND hWnd, LPARAM lParam)
       -{
       -  HFONT GuiFont;
       -
       -  GuiFont = (HFONT)lParam;
       -  SendMessage(hWnd, WM_SETFONT, (WPARAM)GuiFont, MAKELPARAM(FALSE, 0));
       -  return TRUE;
       -}
       -
       -void SetGuiFont(HWND hWnd)
       -{
       -  HFONT GuiFont;
       -
       -  GuiFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
       -  if (GuiFont)
       -    EnumChildWindows(hWnd, enumFunc, (LPARAM)GuiFont);
       -}
 (DIR) diff --git a/win32/guifunc.h b/win32/guifunc.h
       t@@ -1,26 +0,0 @@
       -/************************************************************************
       - * guifunc.h      GUI-specific shared functions for installer           *
       - * Copyright (C)  2001-2004  Ben Webb                                   *
       - *                Email: benwebb@users.sf.net                           *
       - *                WWW: https://dopewars.sourceforge.io/                 *
       - *                                                                      *
       - * This program is free software; you can redistribute it and/or        *
       - * modify it under the terms of the GNU General Public License          *
       - * as published by the Free Software Foundation; either version 2       *
       - * of the License, or (at your option) any later version.               *
       - *                                                                      *
       - * This program is distributed in the hope that it will be useful,      *
       - * but WITHOUT ANY WARRANTY; without even the implied warranty of       *
       - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        *
       - * GNU General Public License for more details.                         *
       - *                                                                      *
       - * You should have received a copy of the GNU General Public License    *
       - * along with this program; if not, write to the Free Software          *
       - * Foundation, Inc., 59 Temple Place - Suite 330, Boston,               *
       - *                   MA  02111-1307, USA.                               *
       - ************************************************************************/
       -
       -#include <windows.h>
       -
       -void RegisterSepClass(HINSTANCE hInstance);
       -void SetGuiFont(HWND hWnd);
 (DIR) diff --git a/win32/makeinstall.c b/win32/makeinstall.c
       t@@ -1,353 +0,0 @@
       -/************************************************************************
       - * makeinstall.c  Program to create install data for setup.c            *
       - * Copyright (C)  2001-2004  Ben Webb                                   *
       - *                Email: benwebb@users.sf.net                           *
       - *                WWW: https://dopewars.sourceforge.io/                 *
       - *                                                                      *
       - * This program is free software; you can redistribute it and/or        *
       - * modify it under the terms of the GNU General Public License          *
       - * as published by the Free Software Foundation; either version 2       *
       - * of the License, or (at your option) any later version.               *
       - *                                                                      *
       - * This program is distributed in the hope that it will be useful,      *
       - * but WITHOUT ANY WARRANTY; without even the implied warranty of       *
       - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        *
       - * GNU General Public License for more details.                         *
       - *                                                                      *
       - * You should have received a copy of the GNU General Public License    *
       - * along with this program; if not, write to the Free Software          *
       - * Foundation, Inc., 59 Temple Place - Suite 330, Boston,               *
       - *                   MA  02111-1307, USA.                               *
       - ************************************************************************/
       -
       -#include <windows.h>
       -#include <stdio.h>
       -#include <stdlib.h>
       -#ifdef LIBBZ2
       -# include "bzlib/bzlib.h"
       -#else
       -# include "zlib/zlib.h"
       -#endif
       -#include "util.h"
       -
       -char *read_line(HANDLE hin)
       -{
       -  char *buf;
       -  int bufsize = 32, strind = 0;
       -  DWORD bytes_read;
       -
       -  buf = bmalloc(bufsize);
       -
       -  while (1) {
       -    if (!ReadFile(hin, &buf[strind], 1, &bytes_read, NULL)) {
       -      printf("Read error\n");
       -      break;
       -    }
       -    if (bytes_read == 0) {
       -      buf[strind] = '\0';
       -      break;
       -    } else if (buf[strind] == '\r')
       -      continue;
       -    else if (buf[strind] == '\n') {
       -      buf[strind++] = '\0';
       -      break;
       -    } else {
       -      strind++;
       -      if (strind >= bufsize) {
       -        bufsize *= 2;
       -        buf = brealloc(buf, bufsize);
       -      }
       -    }
       -  }
       -  if (strind == 0) {
       -    bfree(buf);
       -    return NULL;
       -  } else
       -    return buf;
       -}
       -
       -InstData *ReadInstallData()
       -{
       -  HANDLE fin;
       -  char *line, *line2, *line3, *line4;
       -  InstFiles *lastinst = NULL, *lastextra = NULL, *lastkeep = NULL;
       -  InstLink *lastmenu = NULL, *lastdesktop = NULL;
       -  InstData *idata;
       -  int i;
       -  enum {
       -    S_PRODUCT = 0, S_INSTDIR, S_INSTALL, S_EXTRA, S_KEEP, S_STARTMENUDIR,
       -    S_STARTMENU, S_DESKTOP, S_NTSERVICE, S_NONE
       -  } section = S_NONE;
       -  char *titles[S_NONE] = {
       -    "[product]", "[instdir]", "[install]", "[extrafiles]", "[keepfiles]",
       -    "[startmenudir]", "[startmenu]", "[desktop]", "[NT Service]"
       -  };
       -
       -  idata = bmalloc(sizeof(InstData));
       -  idata->installdir = idata->startmenudir = NULL;
       -  idata->instfiles = idata->extrafiles = idata->keepfiles = NULL;
       -  idata->startmenu = idata->desktop = NULL;
       -  idata->service = NULL;
       -
       -  fin = CreateFile("filelist", GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
       -
       -  if (fin != INVALID_HANDLE_VALUE) {
       -    while (1) {
       -      line = read_line(fin);
       -      if (!line)
       -        break;
       -      if (line[0] == '\0') {
       -        bfree(line);
       -        continue;
       -      }
       -
       -      for (i = S_PRODUCT; i < S_NONE; i++) {
       -        if (strcmp(line, titles[i]) == 0) {
       -          section = i;
       -          break;
       -        }
       -      }
       -      if (i < S_NONE) {
       -        bfree(line);
       -        continue;
       -      }
       -
       -      switch (section) {
       -      case S_NONE:
       -        printf("Bad line %s\n", line);
       -        exit(EXIT_FAILURE);
       -      case S_PRODUCT:
       -        printf("product ID = %s\n", line);
       -        idata->product = line;
       -        break;
       -      case S_INSTDIR:
       -        printf("install dir = %s\n", line);
       -        idata->installdir = line;
       -        break;
       -      case S_STARTMENUDIR:
       -        printf("start menu dir = %s\n", line);
       -        idata->startmenudir = line;
       -        break;
       -      case S_INSTALL:
       -        AddInstFiles(line, 0, &lastinst, &idata->instfiles);
       -        break;
       -      case S_EXTRA:
       -        AddInstFiles(line, 0, &lastextra, &idata->extrafiles);
       -        break;
       -      case S_KEEP:
       -        AddInstFiles(line, 0, &lastkeep, &idata->keepfiles);
       -        break;
       -      case S_STARTMENU:
       -        line2 = read_line(fin);
       -        line3 = read_line(fin);
       -        printf("start menu entry = %s/%s/%s\n", line, line2, line3);
       -        AddInstLink(line, line2, line3, &lastmenu, &idata->startmenu);
       -        break;
       -      case S_NTSERVICE:
       -        line2 = read_line(fin);
       -        line3 = read_line(fin);
       -        line4 = read_line(fin);
       -        printf("NT Service = %s/%s/%s/%s\n", line, line2, line3, line4);
       -        AddServiceDetails(line, line2, line3, line4, &idata->service);
       -        break;
       -      case S_DESKTOP:
       -        line2 = read_line(fin);
       -        line3 = read_line(fin);
       -        printf("desktop entry = %s/%s/%s\n", line, line2, line3);
       -        AddInstLink(line, line2, line3, &lastdesktop, &idata->desktop);
       -        break;
       -      }
       -    }
       -    CloseHandle(fin);
       -  }
       -
       -  if (idata->installdir && idata->startmenudir && idata->product) {
       -    return idata;
       -  } else {
       -    printf("No directories specified\n");
       -    exit(EXIT_FAILURE);
       -  }
       -}
       -
       -#define BUFFER_SIZE (32*1024)
       -#define COMPRESSION 9
       -
       -void OpenNextFile(InstFiles *filelist, InstFiles **listpt, HANDLE *fin)
       -{
       -  char *filename, *sep;
       -
       -  if (*fin)
       -    CloseHandle(*fin);
       -  *fin = NULL;
       -
       -  if (!*listpt)
       -    *listpt = filelist;
       -  else
       -    *listpt = (*listpt)->next;
       -
       -  if (*listpt) {
       -    filename = (*listpt)->filename;
       -    sep = strstr(filename, " -> ");
       -    if (sep)
       -      *sep = '\0';
       -    *fin = CreateFile(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
       -    if (sep)
       -      strcpy(filename, sep + 4);
       -    if (*fin == INVALID_HANDLE_VALUE)
       -      printf("Cannot open file: %s\n", filename);
       -  }
       -}
       -
       -int main()
       -{
       -  HANDLE fout, fin;
       -  DWORD bytes_read, bytes_written;
       -  InstData *idata;
       -  InstFiles *filept;
       -  char *inbuf, *outbuf;
       -  int status, count;
       -  bstr *str;
       -#ifdef LIBBZ2
       -  bz_stream z;
       -#else
       -  z_stream z;
       -#endif
       -
       -  idata = ReadInstallData();
       -
       -  fout = CreateFile("installfiles.z", GENERIC_WRITE, 0, NULL,
       -                    CREATE_ALWAYS, 0, NULL);
       -
       -  outbuf = bmalloc(BUFFER_SIZE);
       -  inbuf = bmalloc(BUFFER_SIZE);
       -
       -#ifdef LIBBZ2
       -  z.bzalloc = NULL;
       -  z.bzfree = NULL;
       -  z.opaque = NULL;
       -  BZ2_bzCompressInit(&z, COMPRESSION, 0, 30);
       -#else
       -  z.zalloc = Z_NULL;
       -  z.zfree  = Z_NULL;
       -  z.opaque = Z_NULL;
       -  deflateInit(&z, COMPRESSION);
       -#endif
       -  z.avail_in = 0;
       -  z.next_out = outbuf;
       -  z.avail_out = BUFFER_SIZE;
       -
       -  filept = NULL;
       -  fin = NULL;
       -  OpenNextFile(idata->instfiles, &filept, &fin);
       -  if (fin == INVALID_HANDLE_VALUE) {
       -    return 1;
       -  }
       -
       -  while (fin != INVALID_HANDLE_VALUE) {
       -    if (z.avail_in == 0) {
       -      z.next_in = inbuf;
       -      bytes_read = 0;
       -      while (!bytes_read && fin) {
       -        if (!ReadFile(fin, inbuf, BUFFER_SIZE, &bytes_read, NULL)) {
       -          printf("Read error\n");
       -          break;
       -        }
       -        filept->filesize += bytes_read;
       -        if (!bytes_read)
       -          OpenNextFile(idata->instfiles, &filept, &fin);
       -      }
       -      z.avail_in = bytes_read;
       -    }
       -#ifdef LIBBZ2
       -    status = BZ2_bzCompress(&z, z.avail_in == 0 ? BZ_FINISH : BZ_RUN);
       -#else
       -    status = deflate(&z, z.avail_in == 0 ? Z_FINISH : Z_NO_FLUSH);
       -#endif
       -    count = BUFFER_SIZE - z.avail_out;
       -    if (!WriteFile(fout, outbuf, count, &bytes_written, NULL)) {
       -      printf("Write error\n");
       -    }
       -    z.next_out = outbuf;
       -    z.avail_out = BUFFER_SIZE;
       -
       -#ifdef LIBBZ2
       -    if (status == BZ_STREAM_END) {
       -      break;
       -    } else if (status != BZ_RUN_OK && status != BZ_FINISH_OK) {
       -      printf("Unexpected bzlib status: %d\n", status);
       -      break;
       -    }
       -#else
       -    if (status == Z_STREAM_END) {
       -      break;
       -    } else if (status != Z_OK) {
       -      printf("Unexpected libz status: %d\n", status);
       -      break;
       -    }
       -#endif
       -  }
       -
       -#ifdef LIBBZ2
       -  printf("Written compressed data: raw %d, compressed %d\n",
       -         z.total_in_lo32, z.total_out_lo32);
       -  bytes_written = z.total_out_lo32;
       -  BZ2_bzCompressEnd(&z);
       -#else
       -  printf("Written compressed data: raw %ld, compressed %ld\n",
       -         z.total_in, z.total_out);
       -  bytes_written = z.total_out;
       -  deflateEnd(&z);
       -#endif
       -
       -  CloseHandle(fout);
       -
       -  fout = CreateFile("manifest", GENERIC_WRITE, 0, NULL,
       -                    CREATE_ALWAYS, 0, NULL);
       -  if (fout == INVALID_HANDLE_VALUE)
       -    printf("Cannot create file list\n");
       -
       -  str = bstr_new();
       -  bstr_setlength(str, 0);
       -  bstr_append_long(str, bytes_written);
       -  if (!WriteFile(fout, str->text, str->length + 1, &bytes_written, NULL)) {
       -    printf("Write error\n");
       -  }
       -
       -  if (!WriteFile(fout, idata->product, strlen(idata->product) + 1,
       -                 &bytes_written, NULL)) {
       -    printf("Write error\n");
       -  }
       -  if (!WriteFile(fout, idata->installdir, strlen(idata->installdir) + 1,
       -                 &bytes_written, NULL)) {
       -    printf("Write error\n");
       -  }
       -  if (!WriteFile
       -      (fout, idata->startmenudir, strlen(idata->startmenudir) + 1,
       -       &bytes_written, NULL)) {
       -    printf("Write error\n");
       -  }
       -
       -  WriteFileList(fout, idata->instfiles);
       -  WriteFileList(fout, idata->extrafiles);
       -
       -  WriteLinkList(fout, idata->startmenu);
       -  WriteLinkList(fout, idata->desktop);
       -
       -  WriteServiceDetails(fout, idata->service);
       -  WriteFileList(fout, idata->keepfiles);
       -
       -  CloseHandle(fout);
       -  bfree(inbuf);
       -  bfree(outbuf);
       -
       -  FreeInstData(idata, TRUE);
       -
       -  return 0;
       -}
       -
       -#ifdef LIBBZ2
       -void bz_internal_error(int errcode)
       -{
       -  printf("bzip error %d\n", errcode);
       -}
       -#endif
 (DIR) diff --git a/win32/setup.c b/win32/setup.c
       t@@ -1,1242 +0,0 @@
       -/************************************************************************
       - * setup.c        Simple Win32 installer for dopewars                   *
       - * Copyright (C)  2001-2004  Ben Webb                                   *
       - *                Email: benwebb@users.sf.net                           *
       - *                WWW: https://dopewars.sourceforge.io/                 *
       - *                                                                      *
       - * This program is free software; you can redistribute it and/or        *
       - * modify it under the terms of the GNU General Public License          *
       - * as published by the Free Software Foundation; either version 2       *
       - * of the License, or (at your option) any later version.               *
       - *                                                                      *
       - * This program is distributed in the hope that it will be useful,      *
       - * but WITHOUT ANY WARRANTY; without even the implied warranty of       *
       - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        *
       - * GNU General Public License for more details.                         *
       - *                                                                      *
       - * You should have received a copy of the GNU General Public License    *
       - * along with this program; if not, write to the Free Software          *
       - * Foundation, Inc., 59 Temple Place - Suite 330, Boston,               *
       - *                   MA  02111-1307, USA.                               *
       - ************************************************************************/
       -
       -#include <windows.h>
       -#include <commctrl.h>
       -#include <stdio.h>
       -#include <stdlib.h>
       -#include <string.h>
       -#ifdef LIBBZ2
       -# include "bzlib/bzlib.h"
       -#else
       -# include "zlib/zlib.h"
       -#endif
       -#include <shlobj.h>
       -
       -#include "contid.h"
       -#include "guifunc.h"
       -#include "util.h"
       -
       -typedef enum {
       -  DL_INTRO = 0,
       -  DL_LICENCE, DL_SHORTCUTS, DL_INSTALLDIR, DL_DOINSTALL, DL_NUM
       -} DialogType;
       -
       -InstData *idata;
       -HWND mainDlg[DL_NUM];
       -DialogType CurrentDialog;
       -HINSTANCE hInst = NULL;
       -char *oldversion = NULL;
       -BOOL services_supported, have_admin_rights, install_all_users;
       -
       -DWORD WINAPI DoInstall(LPVOID lpParam);
       -static void GetWinText(char **text, HWND hWnd);
       -static void FillFolderList(void);
       -
       -/* 
       - * Does this OS version support NT services? If so, do we have the 
       - * necessary (administrator) rights to use them?
       - */
       -void ServiceCheck(BOOL *hasServices, BOOL *isAdmin)
       -{
       -  SC_HANDLE scManager;
       -
       -  scManager = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
       -  if (scManager) {
       -    *hasServices = *isAdmin = TRUE;
       -    CloseServiceHandle(scManager);
       -  } else if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) {
       -    *hasServices = *isAdmin = FALSE;
       -  } else {
       -    *hasServices = TRUE;
       -    *isAdmin = FALSE;
       -  }
       -}
       -
       -BOOL InstallService(InstData *idata)
       -{
       -  SC_HANDLE scManager, scService;
       -  HKEY key;
       -  bstr *str;
       -  static char keyprefix[] = "SYSTEM\\ControlSet001\\Services\\";
       -  NTService *service;
       -
       -  service = idata->service;
       -  if (!service)
       -    return FALSE;
       -
       -  scManager = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
       -
       -  if (!scManager) {
       -    DisplayError("Cannot connect to service manager", TRUE, FALSE);
       -    return FALSE;
       -  }
       -
       -  str = bstr_new();
       -  bstr_assign(str, idata->installdir);
       -  bstr_appendpath(str, service->exe);
       -
       -  scService = CreateService(scManager, service->name, service->display,
       -                            SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
       -                            SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL,
       -                            str->text, NULL, NULL, NULL, NULL, NULL);
       -  if (!scService) {
       -    DisplayError("Cannot create service", TRUE, FALSE);
       -    bstr_free(str, TRUE);
       -    return FALSE;
       -  }
       -
       -  bstr_assign(str, keyprefix);
       -  bstr_append(str, service->name);
       -  if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, str->text,
       -                   0, KEY_WRITE, &key) == ERROR_SUCCESS) {
       -    RegSetValueEx(key, "Description", 0, REG_SZ, service->description,
       -                  strlen(service->description));
       -    RegCloseKey(key);
       -  }
       -
       -  CloseServiceHandle(scService);
       -  CloseServiceHandle(scManager);
       -  return TRUE;
       -}
       -
       -/* 
       - * Checks that the install directory exists, and creates it if it does not.
       - * Returns TRUE if the directory is OK.
       - */
       -BOOL CheckCreateDir(void)
       -{
       -  char *instdir;
       -
       -  GetWinText(&idata->installdir,
       -             GetDlgItem(mainDlg[DL_INSTALLDIR], ED_INSTDIR));
       -  instdir = idata->installdir;
       -  if (SetCurrentDirectory(instdir)) {
       -    return TRUE;
       -  } else {
       -    if (MessageBox(mainDlg[CurrentDialog],
       -                   "The install directory does not exist.\n"
       -                   "Create it?", "Install Directory", MB_YESNO) == IDYES) {
       -      if (CreateWholeDirectory(instdir)) {
       -        return TRUE;
       -      } else {
       -        DisplayError("Could not create directory", TRUE, FALSE);
       -      }
       -    }
       -    return FALSE;
       -  }
       -}
       -
       -void ShowNewDialog(DialogType NewDialog)
       -{
       -  RECT DeskRect, OurRect;
       -  int newX, newY;
       -  HWND hWnd;
       -  HANDLE hThread;
       -  DWORD threadID;
       -
       -  if (NewDialog < 0 || NewDialog >= DL_NUM)
       -    return;
       -
       -  if (NewDialog > CurrentDialog) {
       -    switch (CurrentDialog) {
       -    case DL_INSTALLDIR:
       -      if (!CheckCreateDir())
       -        return;
       -      break;
       -    case DL_INTRO:
       -      install_all_users = (services_supported
       -                           && IsDlgButtonChecked(mainDlg[DL_INTRO],
       -                                                 RB_ALLUSERS) == BST_CHECKED);
       -      FillFolderList();
       -      break;
       -    default:
       -      break;
       -    }
       -  }
       -
       -  hWnd = mainDlg[NewDialog];
       -  if (GetWindowRect(hWnd, &OurRect) &&
       -      GetWindowRect(GetDesktopWindow(), &DeskRect)) {
       -    newX = (DeskRect.left + DeskRect.right + OurRect.left - OurRect.right) / 2;
       -    newY = (DeskRect.top + DeskRect.bottom + OurRect.top - OurRect.bottom) / 2;
       -    SetWindowPos(hWnd, HWND_TOP, newX, newY, 0, 0, SWP_NOSIZE);
       -  }
       -  ShowWindow(hWnd, SW_SHOW);
       -
       -  if (CurrentDialog != DL_NUM)
       -    ShowWindow(mainDlg[CurrentDialog], SW_HIDE);
       -  CurrentDialog = NewDialog;
       -
       -  if (NewDialog == DL_DOINSTALL) {
       -    hThread = CreateThread(NULL, 0, DoInstall, NULL, 0, &threadID);
       -  }
       -}
       -
       -int CALLBACK BrowseCallback(HWND hwnd, UINT msg, LPARAM lParam,
       -                            LPARAM lpData)
       -{
       -  switch (msg) {
       -  case BFFM_INITIALIZED:
       -    SendMessage(hwnd, BFFM_SETSELECTION, TRUE, (LPARAM)idata->installdir);
       -    break;
       -  }
       -  return 0;
       -}
       -
       -void SelectInstDir(HWND parent)
       -{
       -  BROWSEINFO bi = { 0 };
       -  TCHAR path[MAX_PATH];
       -  LPITEMIDLIST pidl;
       -  IMalloc *imalloc = 0;
       -
       -  if (SUCCEEDED(SHGetMalloc(&imalloc))) {
       -    bi.lpszTitle = "Pick a directory";
       -    bi.pszDisplayName = path;
       -    bi.ulFlags = BIF_STATUSTEXT | BIF_RETURNONLYFSDIRS;
       -    bi.lpfn = BrowseCallback;
       -    pidl = SHBrowseForFolder(&bi);
       -    if (pidl) {
       -      if (SHGetPathFromIDList(pidl, path)) {
       -        bfree(idata->installdir);
       -        idata->installdir = bstrdup(path);
       -        SendDlgItemMessage(mainDlg[DL_INSTALLDIR], ED_INSTDIR, WM_SETTEXT,
       -                           0, (LPARAM)idata->installdir);
       -      }
       -      imalloc->lpVtbl->Free(imalloc, pidl);
       -    }
       -    imalloc->lpVtbl->Release(imalloc);
       -  }
       -}
       -
       -void ConditionalExit(HWND hWnd)
       -{
       -  if (MessageBox(hWnd,
       -                 "This will exit without installing any new software on "
       -                 "your machine.\nAre you sure you want to quit?\n\n(You can "
       -                 "continue the installation at a\nlater date simply by "
       -                 "running this program again.)", "Exit Install",
       -                 MB_YESNO | MB_ICONQUESTION) == IDYES) {
       -    PostQuitMessage(0);
       -  }
       -}
       -
       -void UpdateStartMenuFolder(void)
       -{
       -  char *buf;
       -  HWND folderlist;
       -  LRESULT lres;
       -  int selind;
       -
       -  folderlist = GetDlgItem(mainDlg[DL_SHORTCUTS], LB_FOLDLIST);
       -  if (!folderlist)
       -    return;
       -
       -  lres = SendMessage(folderlist, LB_GETCURSEL, 0, 0);
       -  if (lres == LB_ERR)
       -    return;
       -
       -  selind = (int)lres;
       -  lres = SendMessage(folderlist, LB_GETTEXTLEN, (WPARAM)selind, 0);
       -  if (lres == LB_ERR)
       -    return;
       -
       -  buf = bmalloc(lres + 1);
       -  lres = SendMessage(folderlist, LB_GETTEXT, (WPARAM)selind, (LPARAM)buf);
       -  if (lres != LB_ERR) {
       -    SendDlgItemMessage(mainDlg[DL_SHORTCUTS], ED_FOLDER, WM_SETTEXT,
       -                       0, (LPARAM)buf);
       -  }
       -  bfree(buf);
       -}
       -
       -BOOL CALLBACK MainDlgProc(HWND hWnd, UINT msg, WPARAM wParam,
       -                          LPARAM lParam)
       -{
       -  switch (msg) {
       -  case WM_INITDIALOG:
       -    return TRUE;
       -  case WM_COMMAND:
       -    if (HIWORD(wParam) == BN_CLICKED && lParam) {
       -      switch (LOWORD(wParam)) {
       -      case BT_CANCEL:
       -        ConditionalExit(hWnd);
       -        break;
       -      case BT_NEXT:
       -        ShowNewDialog(CurrentDialog + 1);
       -        break;
       -      case BT_BACK:
       -        ShowNewDialog(CurrentDialog - 1);
       -        break;
       -      case BT_FINISH:
       -        PostQuitMessage(0);
       -        break;
       -      case BT_BROWSE:
       -        SelectInstDir(hWnd);
       -        break;
       -      }
       -    } else if (HIWORD(wParam) == LBN_SELCHANGE && lParam &&
       -               LOWORD(wParam) == LB_FOLDLIST) {
       -      UpdateStartMenuFolder();
       -    }
       -    break;
       -  case WM_CLOSE:
       -    ConditionalExit(hWnd);
       -    return TRUE;
       -  }
       -  return FALSE;
       -}
       -
       -LPVOID GetResource(LPCTSTR resname, LPCTSTR restype)
       -{
       -  HRSRC hrsrc;
       -  HGLOBAL hglobal;
       -  LPVOID respt;
       -
       -  hrsrc = FindResource(NULL, resname, restype);
       -  if (!hrsrc)
       -    DisplayError("Could not find resource", TRUE, TRUE);
       -
       -  hglobal = LoadResource(NULL, hrsrc);
       -  if (!hglobal)
       -    DisplayError("Could not load resource", TRUE, TRUE);
       -
       -  respt = LockResource(hglobal);
       -  if (!respt)
       -    DisplayError("Could not lock resource", TRUE, TRUE);
       -
       -  return respt;
       -}
       -
       -InstData *ReadInstData()
       -{
       -  InstFiles *lastinst = NULL, *lastextra = NULL, *lastkeep = NULL;
       -  InstLink *lastmenu = NULL, *lastdesktop = NULL;
       -  char *instdata, *pt, *filename, *line2, *line3, *line4;
       -  bstr *idir;
       -  DWORD filesize;
       -  InstData *idata;
       -
       -  instdata = GetResource(MAKEINTRESOURCE(0), "INSTLIST");
       -  if (!instdata)
       -    return NULL;
       -
       -  pt = instdata;
       -
       -  idata = bmalloc(sizeof(InstData));
       -  idata->flags = 0;
       -  idata->service = NULL;
       -  idata->totalsize = atol(pt);
       -  pt += strlen(pt) + 1;
       -
       -  idata->product = bstrdup(pt);
       -  pt += strlen(pt) + 1;
       -
       -  idir = bstr_new();
       -  bstr_assign_progfilesdir(idir);
       -  bstr_appendpath(idir, pt);
       -  idata->installdir = idir->text;
       -  bstr_free(idir, FALSE);
       -  pt += strlen(pt) + 1;
       -
       -  idata->startmenudir = bstrdup(pt);
       -  pt += strlen(pt) + 1;
       -
       -  while (1) {
       -    filename = pt;
       -    pt += strlen(pt) + 1;
       -    if (filename[0]) {
       -      filesize = atol(pt);
       -      pt += strlen(pt) + 1;
       -      AddInstFiles(filename, filesize, &lastinst, &idata->instfiles);
       -    } else
       -      break;
       -  }
       -  while (1) {
       -    filename = pt;
       -    pt += strlen(pt) + 1;
       -    if (filename[0]) {
       -      filesize = atol(pt);
       -      pt += strlen(pt) + 1;
       -      AddInstFiles(filename, filesize, &lastextra, &idata->extrafiles);
       -    } else
       -      break;
       -  }
       -  while (1) {
       -    filename = pt;
       -    pt += strlen(pt) + 1;
       -    if (filename[0]) {
       -      line2 = pt;
       -      pt += strlen(pt) + 1;
       -      line3 = pt;
       -      pt += strlen(pt) + 1;
       -      AddInstLink(filename, line2, line3, &lastmenu, &idata->startmenu);
       -    } else
       -      break;
       -  }
       -  while (1) {
       -    filename = pt;
       -    pt += strlen(pt) + 1;
       -    if (filename[0]) {
       -      line2 = pt;
       -      pt += strlen(pt) + 1;
       -      line3 = pt;
       -      pt += strlen(pt) + 1;
       -      AddInstLink(filename, line2, line3, &lastdesktop, &idata->desktop);
       -    } else
       -      break;
       -  }
       -  filename = pt;
       -  pt += strlen(pt) + 1;
       -  if (filename[0]) {
       -    line2 = pt;
       -    pt += strlen(pt) + 1;
       -    line3 = pt;
       -    pt += strlen(pt) + 1;
       -    line4 = pt;
       -    pt += strlen(pt) + 1;
       -    AddServiceDetails(filename, line2, line3, line4, &idata->service);
       -  }
       -  while (1) {
       -    filename = pt;
       -    pt += strlen(pt) + 1;
       -    if (filename[0]) {
       -      filesize = atol(pt);
       -      pt += strlen(pt) + 1;
       -      AddInstFiles(filename, filesize, &lastkeep, &idata->keepfiles);
       -    } else
       -      break;
       -  }
       -
       -  return idata;
       -}
       -
       -#define BUFFER_SIZE (32*1024)
       -
       -char *GetFirstFile(InstFiles *filelist, DWORD totalsize)
       -{
       -  DWORD bufsiz;
       -  char *inbuf, *outbuf;
       -  int status;
       -#ifdef LIBBZ2
       -  bz_stream z;
       -#else
       -  z_stream z;
       -#endif
       -
       -  if (!filelist)
       -    return NULL;
       -
       -  inbuf = GetResource(MAKEINTRESOURCE(1), "INSTFILE");
       -  if (!inbuf)
       -    return NULL;
       -
       -  bufsiz = filelist->filesize;
       -  outbuf = bmalloc(bufsiz + 1);
       -
       -#ifdef LIBBZ2
       -  z.bzalloc = NULL;
       -  z.bzfree = NULL;
       -  z.opaque = NULL;
       -  BZ2_bzDecompressInit(&z, 0, 0);
       -#else
       -  z.zalloc = Z_NULL;
       -  z.zfree  = Z_NULL;
       -  z.opaque = Z_NULL;
       -  inflateInit(&z);
       -#endif
       -
       -  z.next_in = inbuf;
       -  z.avail_in = totalsize;
       -  z.next_out = outbuf;
       -  z.avail_out = bufsiz;
       -
       -  while (1) {
       -#ifdef LIBBZ2
       -    status = BZ2_bzDecompress(&z);
       -    if ((status != BZ_OK && status != BZ_STREAM_END) || z.avail_out == 0) {
       -      break;
       -    }
       -#else
       -    status = inflate(&z, Z_SYNC_FLUSH);
       -    if ((status != Z_OK && status != Z_STREAM_END) || z.avail_out == 0) {
       -      break;
       -    }
       -#endif
       -  }
       -
       -#ifdef LIBBZ2
       -  BZ2_bzDecompressEnd(&z);
       -#else
       -  inflateEnd(&z);
       -#endif
       -
       -  outbuf[bufsiz] = '\0';
       -  return outbuf;
       -}
       -
       -BOOL OpenNextOutput(HANDLE *fout, InstFiles *filelist,
       -                    InstFiles *keepfiles, InstFiles **listpt,
       -                    DWORD *fileleft, HANDLE logf, BOOL *skipfile)
       -{
       -  char *filename, *sep;
       -  bstr *str;
       -  InstFiles *keeppt;
       -  DWORD bytes_written;
       -
       -  *skipfile = FALSE;
       -
       -  if (*fout)
       -    CloseHandle(*fout);
       -  *fout = INVALID_HANDLE_VALUE;
       -
       -  str = bstr_new();
       -
       -  if (*listpt) {
       -    if (!WriteFile
       -        (logf, (*listpt)->filename, strlen((*listpt)->filename) + 1,
       -         &bytes_written, NULL)) {
       -      printf("Write error\n");
       -    }
       -
       -    bstr_setlength(str, 0);
       -    bstr_append_long(str, (*listpt)->filesize);
       -    if (!WriteFile(logf, str->text, str->length + 1, &bytes_written, NULL)) {
       -      printf("Write error\n");
       -    }
       -    *listpt = (*listpt)->next;
       -  } else
       -    *listpt = filelist;
       -
       -  if (*listpt) {
       -    filename = (*listpt)->filename;
       -    sep = strrchr(filename, '\\');
       -    if (sep) {
       -      *sep = '\0';
       -      CreateWholeDirectory(filename);
       -      *sep = '\\';
       -    }
       -    keeppt = keepfiles;
       -    while (keeppt && strcmp(keeppt->filename, filename) != 0)
       -      keeppt = keeppt->next;
       -
       -    /* If the file is already installed (filesize!=0), then skip it */
       -    if (keeppt && keeppt->filesize != 0) {
       -      *fout = INVALID_HANDLE_VALUE + 1; /* Make sure the handle is valid */
       -      *skipfile = TRUE;
       -    } else {
       -      *fout = CreateFile(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
       -                         0, NULL);
       -      bstr_assign(str, "Installing file: ");
       -      bstr_append(str, filename);
       -      bstr_append(str, " (size ");
       -      bstr_append_long(str, (*listpt)->filesize);
       -      bstr_append(str, ")");
       -      SendDlgItemMessage(mainDlg[DL_DOINSTALL], ST_FILELIST,
       -                         WM_SETTEXT, 0, (LPARAM)str->text);
       -      if (*fout == INVALID_HANDLE_VALUE) {
       -        bstr_assign(str, "Cannot create file ");
       -        bstr_append(str, filename);
       -        DisplayError(str->text, TRUE, FALSE);
       -      }
       -    }
       -    *fileleft = (*listpt)->filesize;
       -  }
       -
       -  bstr_free(str, TRUE);
       -
       -  return (*fout != INVALID_HANDLE_VALUE);
       -}
       -
       -HRESULT CreateLink(LPCSTR origPath, LPSTR linkArgs, LPSTR workDir,
       -                   LPSTR linkPath, LPSTR linkDesc)
       -{
       -  HRESULT hres;
       -  IShellLink *psl;
       -  IPersistFile *ppf;
       -  WORD wsz[MAX_PATH];
       -
       -  hres = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
       -                          &IID_IShellLink, (void **)&psl);
       -  if (SUCCEEDED(hres)) {
       -    psl->lpVtbl->SetPath(psl, origPath);
       -    if (workDir)
       -      psl->lpVtbl->SetWorkingDirectory(psl, workDir);
       -    if (linkDesc)
       -      psl->lpVtbl->SetDescription(psl, linkDesc);
       -    if (linkArgs)
       -      psl->lpVtbl->SetArguments(psl, linkArgs);
       -    hres = psl->lpVtbl->QueryInterface(psl, &IID_IPersistFile, (void **)&ppf);
       -    if (SUCCEEDED(hres)) {
       -      MultiByteToWideChar(CP_ACP, 0, linkPath, -1, wsz, MAX_PATH);
       -      hres = ppf->lpVtbl->Save(ppf, wsz, TRUE);
       -      ppf->lpVtbl->Release(ppf);
       -    } else {
       -      DisplayError("Cannot write shortcut", FALSE, FALSE);
       -    }
       -    psl->lpVtbl->Release(psl);
       -  } else {
       -    DisplayError("Cannot create shortcut", FALSE, FALSE);
       -  }
       -  return hres;
       -}
       -
       -void GetWinText(char **text, HWND hWnd)
       -{
       -  int textlen;
       -
       -  bfree(*text);
       -  *text = NULL;
       -  if (!hWnd)
       -    return;
       -
       -  textlen = GetWindowTextLength(hWnd) + 1;
       -  if (!textlen)
       -    return;
       -
       -  *text = bmalloc(textlen);
       -  if (!GetWindowText(hWnd, *text, textlen)) {
       -    bfree(*text);
       -    *text = NULL;
       -  }
       -}
       -
       -void CreateLinks(char *linkdir, InstLink *linkpt)
       -{
       -  bstr *linkpath, *origfile;
       -
       -  linkpath = bstr_new();
       -  origfile = bstr_new();
       -
       -  for (; linkpt; linkpt = linkpt->next) {
       -    bstr_assign(linkpath, linkdir);
       -    bstr_appendpath(linkpath, linkpt->linkfile);
       -
       -    bstr_assign(origfile, idata->installdir);
       -    bstr_appendpath(origfile, linkpt->origfile);
       -
       -    CreateLink(origfile->text, linkpt->args, idata->installdir,
       -               linkpath->text, NULL);
       -  }
       -}
       -
       -void SetupShortcuts(HANDLE fout)
       -{
       -  char *startmenu, *desktop;
       -  BOOL dodesktop;
       -
       -  startmenu = GetStartMenuDir(install_all_users, idata);
       -  desktop = GetDesktopDir();
       -
       -  dodesktop =
       -      (IsDlgButtonChecked(mainDlg[DL_SHORTCUTS], CB_DESKTOP) ==
       -       BST_CHECKED);
       -
       -  if (startmenu) {
       -    if (CreateDirectory(startmenu, NULL)) {
       -      CreateLinks(startmenu, idata->startmenu);
       -      WriteLinkList(fout, idata->startmenu);
       -    } else {
       -      DisplayError("Could not create Start Menu directory", TRUE, FALSE);
       -      WriteLinkList(fout, NULL);
       -    }
       -  } else {
       -    WriteLinkList(fout, NULL);
       -  }
       -
       -  if (dodesktop && desktop) {
       -    CreateLinks(desktop, idata->desktop);
       -    WriteLinkList(fout, idata->desktop);
       -  } else {
       -    WriteLinkList(fout, NULL);
       -  }
       -
       -  bfree(startmenu);
       -  bfree(desktop);
       -}
       -
       -void SetupUninstall()
       -{
       -  HKEY key;
       -  DWORD disp;
       -  bstr *str, *uninstexe, *link;
       -  BOOL haveuninstall = FALSE;
       -  char *startmenu;
       -  InstFiles *listpt;
       -
       -  for (listpt = idata->instfiles; listpt; listpt = listpt->next) {
       -    if (strcmp(listpt->filename, "uninstall.exe") == 0) {
       -      haveuninstall = TRUE;
       -      break;
       -    }
       -  }
       -
       -  if (!haveuninstall)
       -    return;
       -
       -  str = bstr_new();
       -  uninstexe = bstr_new();
       -  link = bstr_new();
       -
       -  bstr_assign(str, UninstallKey);
       -  bstr_appendpath(str, idata->product);
       -
       -  if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, str->text, 0, NULL, 0,
       -                     KEY_WRITE, NULL, &key, &disp) == ERROR_SUCCESS) {
       -    RegSetValueEx(key, "DisplayName", 0, REG_SZ, idata->product,
       -                  strlen(idata->product));
       -    bstr_assign_windir(str);
       -    bstr_appendpath(str, UninstallEXE);
       -    bstr_append_c(str, ' ');
       -    bstr_append(str, idata->product);
       -    RegSetValueEx(key, "UninstallString", 0, REG_SZ, str->text,
       -                  str->length);
       -    bstr_assign(str, idata->installdir);
       -    RegSetValueEx(key, "InstallDirectory", 0, REG_SZ, str->text,
       -                  str->length);
       -    RegCloseKey(key);
       -  } else {
       -    DisplayError("Cannot create registry key for uninstall", TRUE, FALSE);
       -  }
       -
       -  bstr_assign_windir(str);
       -  bstr_appendpath(str, "bw-uninstall.exe");
       -  DeleteFile(str->text);
       -
       -  bstr_assign(uninstexe, idata->installdir);
       -  bstr_appendpath(uninstexe, "uninstall.exe");
       -
       -  if (!MoveFile(uninstexe->text, str->text)) {
       -    DisplayError("Unable to create uninstall program", TRUE, FALSE);
       -  }
       -  DeleteFile(uninstexe->text);
       -
       -  startmenu = GetStartMenuDir(install_all_users, idata);
       -  bstr_assign(link, startmenu);
       -  bstr_appendpath(link, "Uninstall ");
       -  bstr_append(link, idata->product);
       -  bstr_append(link, ".LNK");
       -
       -  CreateLink(str->text, idata->product, NULL, link->text, NULL);
       -
       -  bstr_free(link, TRUE);
       -  bstr_free(uninstexe, TRUE);
       -  bstr_free(str, TRUE);
       -  bfree(startmenu);
       -}
       -
       -void StartRemoveOldVersion(char *oldversion, InstData *idata,
       -                           InstData **oldidata, HWND hwnd)
       -{
       -  InstData *old;
       -  bstr *str;
       -  char *oldidir, *startmenu, *desktop;
       -  HANDLE fin;
       -
       -  *oldidata = NULL;
       -
       -  if (!oldversion)
       -    return;
       -
       -  oldidir = GetInstallDir(oldversion);
       -
       -  if (!SetCurrentDirectory(oldidir)) {
       -    str = bstr_new();
       -    bstr_assign(str, "Could not access old version's install directory ");
       -    bstr_append(str, oldidir);
       -    DisplayError(str->text, TRUE, TRUE);
       -  }
       -
       -  fin = CreateFile("install.log", GENERIC_READ, 0, NULL, OPEN_EXISTING,
       -                   0, NULL);
       -
       -  if (fin) {
       -    old = ReadOldInstData(fin, oldversion, oldidir);
       -    CloseHandle(fin);
       -    DeleteFile("install.log");
       -
       -    RemoveService(old->service);
       -    DeleteFileList(old->instfiles, hwnd, idata->keepfiles);
       -    DeleteFileList(old->extrafiles, hwnd, idata->keepfiles);
       -
       -    startmenu = GetStartMenuDir(old->flags & IF_ALLUSERS, old);
       -    desktop = GetDesktopDir();
       -    DeleteLinkList(startmenu, old->startmenu, hwnd);
       -    DeleteLinkList(desktop, old->desktop, hwnd);
       -
       -    RemoveUninstall(startmenu, oldversion, FALSE);
       -
       -    bfree(startmenu);
       -    bfree(desktop);
       -    *oldidata = old;
       -  }
       -}
       -
       -void FinishRemoveOldVersion(char *oldversion, InstData *idata,
       -                            InstData *oldidata)
       -{
       -  InstFiles *keeppt;
       -  bstr *str;
       -  char *desktop, *startmenu;
       -
       -  if (!oldidata)
       -    return;
       -
       -  desktop = GetDesktopDir();
       -
       -  str = bstr_new();
       -  /* If we're installing into a different directory, move config. files
       -   * etc. from the old directory to the new one */
       -  if (strcmp(oldidata->installdir, idata->installdir) != 0 &&
       -      SetCurrentDirectory(oldidata->installdir)) {
       -    for (keeppt = idata->keepfiles; keeppt; keeppt = keeppt->next) {
       -      if (keeppt->filesize != 0) {
       -        bstr_assign(str, idata->installdir);
       -        bstr_appendpath(str, keeppt->filename);
       -        if (CopyFile(keeppt->filename, str->text, FALSE)) {
       -          DeleteFile(keeppt->filename);
       -        }
       -      }
       -    }
       -    SetCurrentDirectory(desktop);       /* Make sure we're not in the
       -                                         * install dir */
       -    if (!RemoveWholeDirectory(oldidata->installdir)) {
       -      bstr_assign(str, "Could not remove old install directory:\n");
       -      bstr_append(str, oldidata->installdir);
       -      bstr_append(str, "\nYou may wish to manually remove it later.");
       -      DisplayError(str->text, FALSE, FALSE);
       -    }
       -  }
       -
       -  if (strcmp(idata->startmenudir, oldidata->startmenudir) != 0) {
       -    SetCurrentDirectory(desktop);       /* Make sure we're not in the menu 
       -                                         * dir */
       -    startmenu = GetStartMenuDir(oldidata->flags & IF_ALLUSERS, oldidata);
       -    if (!RemoveWholeDirectory(startmenu)) {
       -      bstr_assign(str, "Could not remove old Start Menu directory:\n");
       -      bstr_append(str, startmenu);
       -      bstr_append(str, "\nYou may wish to manually remove it later.");
       -      DisplayError(str->text, FALSE, FALSE);
       -    }
       -    bfree(startmenu);
       -  }
       -
       -  /* Remove the old registry key */
       -  bstr_assign(str, UninstallKey);
       -  bstr_appendpath(str, oldversion);
       -  RegDeleteKey(HKEY_LOCAL_MACHINE, str->text);
       -
       -  bfree(desktop);
       -  bstr_free(str, TRUE);
       -
       -  FreeInstData(oldidata, TRUE);
       -  oldversion = NULL;            /* This is freed by FreeInstData */
       -}
       -
       -DWORD WINAPI DoInstall(LPVOID lpParam)
       -{
       -  HANDLE fout, logf, fin;
       -  DWORD bytes_written, fileleft;
       -  BOOL skipfile, service_installed;
       -  char *inbuf, *outbuf;
       -  int status, count;
       -#ifdef LIBBZ2
       -  bz_stream z;
       -#else
       -  z_stream z;
       -#endif
       -  InstFiles *listpt;
       -  InstData *oldidata;
       -
       -  /* Steal the filesize attribute to mark that these files are not already 
       -   * installed */
       -  for (listpt = idata->keepfiles; listpt; listpt = listpt->next) {
       -    listpt->filesize = 0;
       -  }
       -
       -  StartRemoveOldVersion(oldversion, idata, &oldidata,
       -                        GetDlgItem(mainDlg[DL_DOINSTALL], ST_FILELIST));
       -
       -  inbuf = GetResource(MAKEINTRESOURCE(1), "INSTFILE");
       -  if (!inbuf)
       -    return 0;
       -
       -  GetWinText(&idata->startmenudir,
       -             GetDlgItem(mainDlg[DL_SHORTCUTS], ED_FOLDER));
       -
       -  if (!SetCurrentDirectory(idata->installdir)) {
       -    DisplayError("Cannot access install directory", TRUE, TRUE);
       -  }
       -
       -  /* Check for already-installed files */
       -  for (listpt = idata->keepfiles; listpt; listpt = listpt->next) {
       -    fin = CreateFile(listpt->filename, GENERIC_READ, 0, NULL,
       -                     OPEN_EXISTING, 0, NULL);
       -    if (fin != INVALID_HANDLE_VALUE) {
       -      CloseHandle(fin);
       -      listpt->filesize = 1;
       -    }
       -  }
       -
       -  logf = CreateFile("install.log", GENERIC_WRITE, 0, NULL,
       -                    CREATE_ALWAYS, 0, NULL);
       -
       -  if (!WriteFile(logf, idata->startmenudir,
       -                 strlen(idata->startmenudir) + 1,
       -                 &bytes_written, NULL)) {
       -    printf("Write error\n");
       -  }
       -
       -  fout = INVALID_HANDLE_VALUE;
       -  listpt = NULL;
       -  OpenNextOutput(&fout, idata->instfiles, idata->keepfiles,
       -                 &listpt, &fileleft, logf, &skipfile);
       -
       -  outbuf = bmalloc(BUFFER_SIZE);
       -
       -#ifdef LIBBZ2
       -  z.bzalloc = NULL;
       -  z.bzfree  = NULL;
       -  z.opaque  = NULL;
       -  BZ2_bzDecompressInit(&z, 0, 0);
       -#else
       -  z.zalloc = Z_NULL;
       -  z.zfree  = Z_NULL;
       -  z.opaque = Z_NULL;
       -  inflateInit(&z);
       -#endif
       -
       -  z.avail_in  = idata->totalsize;
       -  z.next_in   = inbuf;
       -  z.next_out  = outbuf;
       -  z.avail_out = BUFFER_SIZE;
       -
       -  while (1) {
       -#ifdef LIBBZ2
       -    status = BZ2_bzDecompress(&z);
       -    if (status == BZ_OK || status == BZ_STREAM_END) {
       -#else
       -    status = inflate(&z, Z_SYNC_FLUSH);
       -    if (status == Z_OK || status == Z_STREAM_END) {
       -#endif
       -      count = BUFFER_SIZE - z.avail_out;
       -      z.next_out = outbuf;
       -      while (count >= fileleft) {
       -        if (fileleft && !skipfile
       -            && !WriteFile(fout, z.next_out, fileleft, &bytes_written, NULL)) {
       -          printf("Write error\n");
       -        }
       -        count -= fileleft;
       -        z.next_out += fileleft;
       -        if (!OpenNextOutput(&fout, idata->instfiles, idata->keepfiles,
       -                            &listpt, &fileleft, logf, &skipfile))
       -          break;
       -      }
       -      if (fout == INVALID_HANDLE_VALUE)
       -        break;
       -      if (count && !skipfile
       -          && !WriteFile(fout, z.next_out, count, &bytes_written, NULL)) {
       -        printf("Write error\n");
       -      }
       -      fileleft -= count;
       -      z.next_out = outbuf;
       -      z.avail_out = BUFFER_SIZE;
       -    }
       -#ifdef LIBBZ2
       -    if (status != BZ_OK) {
       -      break;
       -    }
       -#else
       -    if (status != Z_OK) {
       -      break;
       -    }
       -#endif
       -  }
       -
       -#ifdef LIBBZ2
       -  BZ2_bzDecompressEnd(&z);
       -#else
       -  inflateEnd(&z);
       -#endif
       -  if (!skipfile)
       -    CloseHandle(fout);
       -
       -  outbuf[0] = '\0';
       -  if (!WriteFile(logf, outbuf, 1, &bytes_written, NULL)) {
       -    printf("Write error\n");
       -  }
       -  bfree(outbuf);
       -
       -  WriteFileList(logf, idata->extrafiles);
       -
       -  FinishRemoveOldVersion(oldversion, idata, oldidata);
       -
       -  if (services_supported) {
       -    service_installed = InstallService(idata);
       -  } else {
       -    service_installed = FALSE;
       -  }
       -
       -  if (service_installed) {
       -    MessageBox(mainDlg[CurrentDialog],
       -               "The dopewars server has been installed as an NT Service, "
       -               "and configured\nfor manual startup. To start or stop this "
       -               "service, or to configure it to run\nautomatically when "
       -               "you turn on your computer, see the \"Services\" application\n"
       -               "from Control Panel. You can also run an interactive server "
       -               "by using\nthe \"dopewars server\" shortcut from the desktop "
       -               "and/or Start Menu.", "Service Installed",
       -               MB_ICONINFORMATION | MB_OK);
       -  }
       -
       -  CoInitialize(NULL);
       -  SetupShortcuts(logf);
       -  SetupUninstall();
       -  CoUninitialize();
       -
       -  WriteServiceDetails(logf, service_installed ? idata->service : NULL);
       -
       -  if (install_all_users) {
       -    idata->flags |= IF_ALLUSERS;
       -  }
       -  WriteInstFlags(logf, idata->flags);
       -
       -  CloseHandle(logf);
       -
       -  SetFileAttributes("install.log", FILE_ATTRIBUTE_HIDDEN);
       -
       -  ShowWindow(GetDlgItem(mainDlg[DL_DOINSTALL], ST_COMPLETE), SW_SHOW);
       -  ShowWindow(GetDlgItem(mainDlg[DL_DOINSTALL], ST_EXIT), SW_SHOW);
       -  EnableWindow(GetDlgItem(mainDlg[DL_DOINSTALL], BT_FINISH), TRUE);
       -  return 0;
       -}
       -
       -void FillFolderList(void)
       -{
       -  HANDLE findfile;
       -  WIN32_FIND_DATA finddata;
       -  bstr *str;
       -  char *startdir;
       -  HWND folderlist;
       -
       -  folderlist = GetDlgItem(mainDlg[DL_SHORTCUTS], LB_FOLDLIST);
       -  if (!folderlist)
       -    return;
       -
       -  SendMessage(folderlist, LB_RESETCONTENT, 0, 0);
       -
       -  str = bstr_new();
       -
       -  startdir = GetStartMenuTopDir(install_all_users);
       -  bstr_assign(str, startdir);
       -  bfree(startdir);
       -  bstr_appendpath(str, "Programs\\*");
       -
       -  findfile = FindFirstFile(str->text, &finddata);
       -  if (findfile != INVALID_HANDLE_VALUE) {
       -    while (1) {
       -      if (finddata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
       -          && strcmp(finddata.cFileName, ".") != 0
       -          && strcmp(finddata.cFileName, "..") != 0) {
       -        SendMessage(folderlist, LB_ADDSTRING, 0,
       -                    (LPARAM)finddata.cFileName);
       -      }
       -      if (!FindNextFile(findfile, &finddata))
       -        break;
       -    }
       -    FindClose(findfile);
       -  }
       -  bstr_free(str, TRUE);
       -}
       -
       -BOOL CheckAdminRights(void)
       -{
       -  return (!services_supported || have_admin_rights
       -          || MessageBox(NULL,
       -                        "To successfully install all components of this "
       -                        "program Administrator\nrights are required, and you "
       -                        "do not appear to have them. Do you want\nto attempt "
       -                        "to continue the installation anyway?",
       -                        "Administrator rights not found",
       -                        MB_YESNO | MB_DEFBUTTON2) == IDYES);
       -}
       -
       -BOOL CheckExistingInstall(InstData *idata)
       -{
       -  bstr *str;
       -  char *sep, *prodname, *prodversion;
       -  char *subkey;
       -  int sublen;
       -  DWORD sublencp;
       -  HKEY key;
       -  DWORD ind;
       -  FILETIME ftime;
       -  BOOL retval = TRUE;
       -
       -  str = bstr_new();
       -  bstr_assign(str, UninstallKey);
       -  bstr_appendpath(str, idata->product);
       -
       -  /* Split product into name and version */
       -  sep = strrchr(idata->product, '-');
       -
       -  if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, str->text, 0, KEY_READ, &key) ==
       -      ERROR_SUCCESS) {
       -    RegCloseKey(key);
       -    if (MessageBox(NULL, "This program appears to already be installed.\n"
       -                   "Are you sure you want to go ahead and install it anyway?",
       -                   idata->product, MB_YESNO) == IDNO)
       -      retval = FALSE;
       -  } else if (sep) {
       -    *sep = '\0';
       -    prodversion = sep + 1;
       -    prodname = bstrdup(idata->product);
       -    *sep = '-';
       -    sublencp = sublen = strlen(idata->product) + 30;
       -    subkey = bmalloc(sublen);
       -    if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, UninstallKey, 0,
       -                     KEY_READ, &key) == ERROR_SUCCESS) {
       -      ind = 0;
       -      while (RegEnumKeyEx(key, ind++, subkey, &sublencp,
       -                          NULL, NULL, NULL, &ftime) == ERROR_SUCCESS) {
       -        sublencp = sublen;
       -        sep = strrchr(subkey, '-');
       -        if (sep) {
       -          *sep = '\0';
       -          if (strcmp(subkey, prodname) == 0) {
       -            bstr_assign(str, "You are trying to install ");
       -            bstr_append(str, idata->product);
       -            bstr_append(str, ".\nHowever, version ");
       -            bstr_append(str, sep + 1);
       -            bstr_append(str, " appears to already be installed.\n"
       -                        "Do you want to replace the existing version with "
       -                        "this one?\n(If you answer \"No\", and continue, "
       -                        "both versions will be installed.)");
       -            if (MessageBox(NULL, str->text, "Existing version",
       -                           MB_YESNO) == IDYES) {
       -              *sep = '-';
       -              oldversion = bstrdup(subkey);
       -            }
       -            break;
       -          }
       -        }
       -      }
       -      RegCloseKey(key);
       -    }
       -    bfree(prodname);
       -    bfree(subkey);
       -  }
       -  bstr_free(str, TRUE);
       -  return retval;
       -}
       -
       -BOOL SetDefaultInstall(void)
       -{
       -  HWND dlg;
       -
       -  dlg = mainDlg[DL_INTRO];
       -
       -  if (services_supported) {
       -    CheckRadioButton(dlg, RB_ALLUSERS, RB_ONEUSER,
       -                     have_admin_rights ? RB_ALLUSERS : RB_ONEUSER);
       -  } else {
       -    ShowWindow(GetDlgItem(dlg, RB_ALLUSERS), SW_HIDE);
       -    ShowWindow(GetDlgItem(dlg, RB_ONEUSER), SW_HIDE);
       -  }
       -
       -  return have_admin_rights;
       -}
       -
       -int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
       -                     LPSTR lpszCmdParam, int nCmdShow)
       -{
       -  MSG msg;
       -  int i;
       -  BOOL Handled;
       -  char *licence;
       -
       -  InitCommonControls();
       -
       -  hInst = hInstance;
       -
       -  if (!hPrevInstance)
       -    RegisterSepClass(hInstance);
       -
       -  for (i = 0; i < DL_NUM; i++) {
       -    mainDlg[i] =
       -        CreateDialog(hInst, MAKEINTRESOURCE(i + 1), NULL, MainDlgProc);
       -  }
       -
       -  ServiceCheck(&services_supported, &have_admin_rights);
       -
       -  install_all_users = SetDefaultInstall();
       -
       -  CheckDlgButton(mainDlg[DL_SHORTCUTS], CB_DESKTOP, BST_CHECKED);
       -  EnableWindow(GetDlgItem(mainDlg[DL_DOINSTALL], BT_FINISH), FALSE);
       -
       -  ShowWindow(GetDlgItem(mainDlg[DL_DOINSTALL], ST_COMPLETE), SW_HIDE);
       -  ShowWindow(GetDlgItem(mainDlg[DL_DOINSTALL], ST_EXIT), SW_HIDE);
       -
       -  idata = ReadInstData();
       -
       -  SendDlgItemMessage(mainDlg[DL_SHORTCUTS], ED_FOLDER, WM_SETTEXT,
       -                     0, (LPARAM)idata->startmenudir);
       -  SendDlgItemMessage(mainDlg[DL_INSTALLDIR], ED_INSTDIR, WM_SETTEXT,
       -                     0, (LPARAM)idata->installdir);
       -
       -  licence = GetFirstFile(idata->instfiles, idata->totalsize);
       -
       -  if (licence) {
       -    SendDlgItemMessage(mainDlg[DL_LICENCE], ED_LICENCE, WM_SETTEXT,
       -                       0, (LPARAM)licence);
       -    bfree(licence);
       -  }
       -
       -  for (i = 0; i < DL_NUM; i++)
       -    SetGuiFont(mainDlg[i]);
       -
       -  if (CheckAdminRights() && CheckExistingInstall(idata)) {
       -    CurrentDialog = DL_NUM;
       -    ShowNewDialog(DL_INTRO);
       -
       -    while (GetMessage(&msg, NULL, 0, 0)) {
       -      Handled = FALSE;
       -      for (i = 0; i < DL_NUM && !Handled; i++) {
       -        Handled = IsDialogMessage(mainDlg[i], &msg);
       -      }
       -      if (!Handled) {
       -        TranslateMessage(&msg);
       -        DispatchMessage(&msg);
       -      }
       -    }
       -  }
       -  FreeInstData(idata, FALSE);
       -
       -  return 0;
       -}
       -
       -#ifdef LIBBZ2
       -void bz_internal_error(int errcode)
       -{
       -}
       -#endif
 (DIR) diff --git a/win32/setup.ico b/win32/setup.ico
       Binary files differ.
 (DIR) diff --git a/win32/setup.manifest b/win32/setup.manifest
       t@@ -1,21 +0,0 @@
       -<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
       -<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
       -<assemblyIdentity
       -    name="setup"
       -    processorArchitecture="x86"
       -    version="1.0.0.0"
       -    type="win32"/>
       -<description>dopewars drug dealing game setup program</description>
       -<dependency>
       -    <dependentAssembly>
       -        <assemblyIdentity
       -            type="win32"
       -            name="Microsoft.Windows.Common-Controls"
       -            version="6.0.0.0"
       -            processorArchitecture="x86"
       -            publicKeyToken="6595b64144ccf1df"
       -            language="*"
       -        />
       -    </dependentAssembly>
       -</dependency>
       -</assembly>
 (DIR) diff --git a/win32/setup.rc b/win32/setup.rc
       t@@ -1,8 +0,0 @@
       -#include <windows.h>
       -
       -1   24        "setup.manifest"
       -
       -0   INSTLIST  "manifest"
       -1   INSTFILE  "installfiles.z"
       -
       -#include "dialogs.rc"
 (DIR) diff --git a/win32/uninstall.c b/win32/uninstall.c
       t@@ -1,196 +0,0 @@
       -/************************************************************************
       - * uninstall.c    Simple Win32 uninstaller for dopewars                 *
       - * Copyright (C)  2001-2004  Ben Webb                                   *
       - *                Email: benwebb@users.sf.net                           *
       - *                WWW: https://dopewars.sourceforge.io/                 *
       - *                                                                      *
       - * This program is free software; you can redistribute it and/or        *
       - * modify it under the terms of the GNU General Public License          *
       - * as published by the Free Software Foundation; either version 2       *
       - * of the License, or (at your option) any later version.               *
       - *                                                                      *
       - * This program is distributed in the hope that it will be useful,      *
       - * but WITHOUT ANY WARRANTY; without even the implied warranty of       *
       - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        *
       - * GNU General Public License for more details.                         *
       - *                                                                      *
       - * You should have received a copy of the GNU General Public License    *
       - * along with this program; if not, write to the Free Software          *
       - * Foundation, Inc., 59 Temple Place - Suite 330, Boston,               *
       - *                   MA  02111-1307, USA.                               *
       - ************************************************************************/
       -
       -#include <windows.h>
       -#include <stdio.h>
       -#include <stdlib.h>
       -#include <string.h>
       -#include "contid.h"
       -#include "guifunc.h"
       -#include "util.h"
       -
       -HINSTANCE hInst;
       -HWND mainDlg;
       -char *product;
       -
       -char *GetProduct(void)
       -{
       -  char *product;
       -
       -  product = strrchr(GetCommandLine(), ' ');
       -  if (product && strlen(product + 1) > 0)
       -    return bstrdup(++product);
       -  else {
       -    DisplayError("This program should be called with a product ID",
       -                 FALSE, TRUE);
       -    ExitProcess(1);
       -  }
       -}
       -
       -DWORD WINAPI DoUninstall(LPVOID lpParam)
       -{
       -  InstData *idata;
       -  HANDLE fin;
       -  HWND delstat;
       -  bstr *str;
       -  char *startmenu, *desktop, *installdir;
       -
       -  installdir = GetInstallDir(product);
       -
       -  if (!SetCurrentDirectory(installdir)) {
       -    str = bstr_new();
       -    bstr_assign(str, "Could not access install directory ");
       -    bstr_append(str, installdir);
       -    DisplayError(str->text, TRUE, TRUE);
       -    /* Pointless to try to free the bstr, since DisplayError ends the
       -     * process */
       -  }
       -
       -  fin = CreateFile("install.log", GENERIC_READ, 0, NULL,
       -                   OPEN_EXISTING, 0, NULL);
       -
       -  if (fin) {
       -    idata = ReadOldInstData(fin, product, installdir);
       -    CloseHandle(fin);
       -    DeleteFile("install.log");
       -
       -    RemoveService(idata->service);
       -
       -    delstat = GetDlgItem(mainDlg, ST_DELSTAT);
       -    DeleteFileList(idata->instfiles, delstat, NULL);
       -    DeleteFileList(idata->extrafiles, delstat, NULL);
       -
       -    startmenu = GetStartMenuDir(idata->flags & IF_ALLUSERS, idata);
       -    desktop = GetDesktopDir();
       -    DeleteLinkList(startmenu, idata->startmenu, delstat);
       -    DeleteLinkList(desktop, idata->desktop, delstat);
       -
       -    RemoveUninstall(startmenu, product, TRUE);
       -
       -    SetCurrentDirectory(desktop);       /* Just make sure we're not in the 
       -                                         * install directory any more */
       -
       -    str = bstr_new();
       -    if (!RemoveWholeDirectory(installdir)) {
       -      bstr_assign(str, "Could not remove install directory:\n");
       -      bstr_append(str, installdir);
       -      bstr_append(str, "\nYou may wish to manually remove it later.");
       -      DisplayError(str->text, FALSE, FALSE);
       -    }
       -
       -    if (!RemoveWholeDirectory(startmenu)) {
       -      bstr_assign(str, "Could not remove Start Menu directory:\n");
       -      bstr_append(str, startmenu);
       -      bstr_append(str, "\nYou may wish to manually remove it later.");
       -      DisplayError(str->text, FALSE, FALSE);
       -    }
       -
       -    bstr_assign(str, UninstallKey);
       -    bstr_appendpath(str, product);
       -    RegDeleteKey(HKEY_LOCAL_MACHINE, str->text);
       -    bstr_free(str, TRUE);
       -
       -    bfree(startmenu);
       -    bfree(desktop);
       -    FreeInstData(idata, TRUE);
       -  } else {
       -    bfree(product);
       -    bfree(installdir);          /* Normally FreeInstData frees these */
       -    str = bstr_new();
       -    bstr_assign(str, "Could not read install.log from ");
       -    bstr_append(str, installdir);
       -    DisplayError(str->text, TRUE, TRUE);
       -    /* Pointless to try to free the bstr, since DisplayError ends the
       -     * process */
       -  }
       -  ShowWindow(GetDlgItem(mainDlg, ST_DELDONE), SW_SHOW);
       -  EnableWindow(GetDlgItem(mainDlg, BT_DELOK), TRUE);
       -  SetFocus(GetDlgItem(mainDlg, BT_DELOK));
       -  return 0;
       -}
       -
       -BOOL CALLBACK MainDlgProc(HWND hWnd, UINT msg, WPARAM wParam,
       -                          LPARAM lParam)
       -{
       -  HANDLE hThread;
       -  DWORD threadID;
       -  static BOOL startedun = FALSE;
       -
       -  switch (msg) {
       -  case WM_INITDIALOG:
       -    return TRUE;
       -  case WM_SHOWWINDOW:
       -    if (wParam && !startedun) {
       -      startedun = TRUE;
       -      hThread = CreateThread(NULL, 0, DoUninstall, NULL, 0, &threadID);
       -    }
       -    return TRUE;
       -  case WM_COMMAND:
       -    if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == BT_DELOK
       -        && lParam) {
       -      PostQuitMessage(0);
       -      return TRUE;
       -    }
       -    break;
       -  case WM_CLOSE:
       -    PostQuitMessage(0);
       -    return TRUE;
       -  }
       -  return FALSE;
       -}
       -
       -int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
       -                     LPSTR lpszCmdParam, int nCmdShow)
       -{
       -  MSG msg;
       -  bstr *str;
       -
       -  product = GetProduct();
       -
       -  str = bstr_new();
       -  bstr_assign(str, "Are you sure you want to uninstall ");
       -  bstr_append(str, product);
       -  bstr_append(str, " ?");
       -  if (MessageBox(NULL, str->text, "Uninstall", MB_YESNO) == IDNO)
       -    return (1);
       -  bstr_free(str, TRUE);
       -
       -  hInst = hInstance;
       -  if (!hPrevInstance)
       -    RegisterSepClass(hInstance);
       -
       -  mainDlg = CreateDialog(hInstance, MAKEINTRESOURCE(1), NULL, MainDlgProc);
       -  SetGuiFont(mainDlg);
       -
       -  EnableWindow(GetDlgItem(mainDlg, BT_DELOK), FALSE);
       -  ShowWindow(mainDlg, SW_SHOW);
       -  ShowWindow(GetDlgItem(mainDlg, ST_DELDONE), SW_HIDE);
       -
       -  while (GetMessage(&msg, NULL, 0, 0)) {
       -    if (!IsDialogMessage(mainDlg, &msg)) {
       -      TranslateMessage(&msg);
       -      DispatchMessage(&msg);
       -    }
       -  }
       -
       -  return 0;
       -}
 (DIR) diff --git a/win32/uninstall.manifest b/win32/uninstall.manifest
       t@@ -1,21 +0,0 @@
       -<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
       -<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
       -<assemblyIdentity
       -    name="uninstall"
       -    processorArchitecture="x86"
       -    version="1.0.0.0"
       -    type="win32"/>
       -<description>dopewars drug dealing game uninstall program</description>
       -<dependency>
       -    <dependentAssembly>
       -        <assemblyIdentity
       -            type="win32"
       -            name="Microsoft.Windows.Common-Controls"
       -            version="6.0.0.0"
       -            processorArchitecture="x86"
       -            publicKeyToken="6595b64144ccf1df"
       -            language="*"
       -        />
       -    </dependentAssembly>
       -</dependency>
       -</assembly>
 (DIR) diff --git a/win32/uninstall.rc b/win32/uninstall.rc
       t@@ -1,16 +0,0 @@
       -#include <windows.h>
       -#include "contid.h"
       -
       -1 24 "uninstall.manifest"
       -
       -mainicon ICON "setup.ico"
       -
       -1 DIALOG 17, 40, 190, 115
       -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
       -CAPTION "Uninstall"
       -BEGIN
       -        CONTROL "", 101, "WC_GTKSEP", 2 | WS_CHILD | WS_VISIBLE, 8, 88, 174, 2
       -        DEFPUSHBUTTON "OK", BT_DELOK, 75, 96, 39, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP
       -        LTEXT "Deleting file: dopewars.exe", ST_DELSTAT, 15, 14, 159, 17, WS_CHILD | WS_VISIBLE | WS_GROUP
       -        LTEXT "All files successfully uninstalled.", ST_DELDONE, 15, 51, 159, 25, WS_CHILD | WS_VISIBLE | WS_GROUP
       -END
 (DIR) diff --git a/win32/util.c b/win32/util.c
       t@@ -1,896 +0,0 @@
       -/************************************************************************
       - * util.c         Shared functions for Win32 installer programs         *
       - * Copyright (C)  2001-2004  Ben Webb                                   *
       - *                Email: benwebb@users.sf.net                           *
       - *                WWW: https://dopewars.sourceforge.io/                 *
       - *                                                                      *
       - * This program is free software; you can redistribute it and/or        *
       - * modify it under the terms of the GNU General Public License          *
       - * as published by the Free Software Foundation; either version 2       *
       - * of the License, or (at your option) any later version.               *
       - *                                                                      *
       - * This program is distributed in the hope that it will be useful,      *
       - * but WITHOUT ANY WARRANTY; without even the implied warranty of       *
       - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        *
       - * GNU General Public License for more details.                         *
       - *                                                                      *
       - * You should have received a copy of the GNU General Public License    *
       - * along with this program; if not, write to the Free Software          *
       - * Foundation, Inc., 59 Temple Place - Suite 330, Boston,               *
       - *                   MA  02111-1307, USA.                               *
       - ************************************************************************/
       -
       -#include <windows.h>
       -#include <stdio.h>
       -#include <string.h>
       -#include <shlobj.h>
       -#include "util.h"
       -
       -const char *UninstallKey =
       -    "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
       -const char *UninstallEXE = "bw-uninstall.exe";
       -
       -static void bstr_append_dir(bstr *str, BOOL windir);
       -
       -void *bmalloc(UINT numbytes)
       -{
       -  HLOCAL localpt;
       -
       -  if (numbytes <= 0)
       -    numbytes = 1;
       -
       -  localpt = LocalAlloc(LMEM_FIXED, numbytes);
       -  if (localpt)
       -    return (void *)localpt;
       -  else {
       -    DisplayError("Could not allocate memory: ", TRUE, TRUE);
       -    ExitProcess(1);
       -  }
       -}
       -
       -void bfree(void *pt)
       -{
       -  if (!pt)
       -    return;
       -  if (LocalFree((HLOCAL) pt)) {
       -    DisplayError("Could not free memory: ", TRUE, TRUE);
       -  }
       -}
       -
       -void *brealloc(void *pt, UINT numbytes)
       -{
       -  UINT numcp;
       -  void *newpt;
       -
       -  if (!pt && numbytes)
       -    return bmalloc(numbytes);
       -  else if (pt && !numbytes) {
       -    bfree(pt);
       -  } else if (pt && numbytes) {
       -    newpt = bmalloc(numbytes);
       -    memset(newpt, 0, numbytes);
       -    numcp = LocalSize((HLOCAL) pt);
       -    if (numbytes < numcp)
       -      numcp = numbytes;
       -    memcpy((char *)newpt, (char *)pt, numcp);
       -    bfree(pt);
       -    return newpt;
       -  }
       -  return NULL;
       -}
       -
       -char *bstrdup(char *str)
       -{
       -  char *newstr;
       -
       -  if (str) {
       -    newstr = bmalloc(strlen(str) + 1);
       -    strcpy(newstr, str);
       -  } else {
       -    newstr = bmalloc(1);
       -    newstr[0] = '\0';
       -  }
       -  return newstr;
       -}
       -
       -bstr *bstr_new(void)
       -{
       -  bstr *str;
       -  str = bmalloc(sizeof(bstr));
       -  str->bufsiz = 64;
       -  str->length = 0;
       -  str->text = bmalloc(str->bufsiz);
       -  str->text[0] = '\0';
       -  return str;
       -}
       -
       -void bstr_free(bstr *str, BOOL free_text)
       -{
       -  if (free_text)
       -    bfree(str->text);
       -  bfree(str);
       -}
       -
       -void bstr_expandby(bstr *str, unsigned extralength)
       -{
       -  if (str->bufsiz >= str->length + 1 + extralength)
       -    return;
       -
       -  while (str->bufsiz < str->length + 1 + extralength)
       -    str->bufsiz *= 2;
       -  str->text = brealloc(str->text, str->bufsiz);
       -}
       -
       -void bstr_setlength(bstr *str, unsigned length)
       -{
       -  if (length <= str->length) {
       -    str->length = length;
       -    str->text[length] = '\0';
       -  } else {
       -    bstr_expandby(str, length - str->length);
       -  }
       -}
       -
       -void bstr_assign(bstr *str, const char *text)
       -{
       -  if (text) {
       -    bstr_setlength(str, strlen(text));
       -    strcpy(str->text, text);
       -    str->length = strlen(text);
       -  } else {
       -    bstr_setlength(str, 0);
       -  }
       -}
       -
       -void bstr_append(bstr *str, const char *text)
       -{
       -  if (!text)
       -    return;
       -  bstr_expandby(str, strlen(text));
       -  strcat(str->text, text);
       -  str->length += strlen(text);
       -}
       -
       -void bstr_appendpath(bstr *str, const char *text)
       -{
       -  if (str->length && str->text[str->length - 1] != '\\') {
       -    bstr_append_c(str, '\\');
       -  }
       -  bstr_append(str, text);
       -}
       -
       -void bstr_append_c(bstr *str, char ch)
       -{
       -  bstr_expandby(str, 1);
       -  str->text[str->length] = ch;
       -  str->length++;
       -  str->text[str->length] = '\0';
       -}
       -
       -/* We can be pretty confident that this is enough space for an integer */
       -#define MAX_LENGTH_INT 80
       -
       -void bstr_append_long(bstr *str, long val)
       -{
       -  char tmpbuf[MAX_LENGTH_INT];
       -
       -  sprintf(tmpbuf, "%ld", val);
       -  bstr_append(str, tmpbuf);
       -}
       -
       -void bstr_append_windir(bstr *str)
       -{
       -  bstr_append_dir(str, TRUE);
       -}
       -
       -void bstr_append_curdir(bstr *str)
       -{
       -  bstr_append_dir(str, FALSE);
       -}
       -
       -void bstr_assign_windir(bstr *str)
       -{
       -  bstr_setlength(str, 0);
       -  bstr_append_windir(str);
       -}
       -
       -void bstr_assign_curdir(bstr *str)
       -{
       -  bstr_setlength(str, 0);
       -  bstr_append_curdir(str);
       -}
       -
       -void bstr_assign_progfilesdir(bstr *str)
       -{
       -  bstr_setlength(str, 0);
       -  bstr_append_progfilesdir(str);
       -}
       -
       -void bstr_append_progfilesdir(bstr *str)
       -{
       -  HKEY key;
       -  static const char *subkey = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion";
       -  static const char *subval = "ProgramFilesDir";
       -  DWORD keylen, keytype;
       -  BOOL ok = FALSE;
       -
       -  if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, subkey, 0,
       -                   KEY_READ, &key) == ERROR_SUCCESS) {
       -    if (RegQueryValueEx(key, subval, NULL,
       -                        &keytype, NULL, &keylen) == ERROR_SUCCESS &&
       -        keytype == REG_SZ) {
       -      char *progfiledir = bmalloc(keylen);
       -
       -      if (RegQueryValueEx(key, subval, NULL,
       -                          &keytype, progfiledir, &keylen) == ERROR_SUCCESS) {
       -        bstr_append(str, progfiledir);
       -        ok = TRUE;
       -      }
       -      bfree(progfiledir);
       -    }
       -    RegCloseKey(key);
       -  }
       -  if (!ok) {
       -    bstr_append(str, "C:\\Program Files");
       -  }
       -}
       -
       -void bstr_append_dir(bstr *str, BOOL windir)
       -{
       -  unsigned spaceleft;
       -  UINT retval;
       -  int tries;
       -
       -  spaceleft = str->bufsiz - str->length;        /* spaceleft includes the
       -                                                 * null */
       -
       -  for (tries = 0; tries < 5; tries++) {
       -    if (windir) {
       -      retval = GetWindowsDirectory(str->text + str->length, spaceleft);
       -    } else {
       -      retval = GetCurrentDirectory(spaceleft, str->text + str->length);
       -    }
       -    if (retval == 0)
       -      DisplayError("Cannot get directory: ", TRUE, TRUE);
       -    if (retval <= spaceleft - 1) {
       -      str->length += retval;
       -      break;
       -    }
       -    bstr_expandby(str, retval); /* Let's err on the side of caution */
       -    spaceleft = str->bufsiz - str->length;
       -  }
       -  if (tries >= 5)
       -    DisplayError("Cannot get directory: ", TRUE, TRUE);
       -}
       -
       -void DisplayError(const char *errtext, BOOL addsyserr, BOOL fatal)
       -{
       -  DWORD syserr;
       -  bstr *str;
       -  LPTSTR lpMsgBuf;
       -
       -  syserr = GetLastError();
       -
       -  str = bstr_new();
       -  bstr_assign(str, errtext);
       -
       -  if (addsyserr) {
       -    bstr_append(str, "; ");
       -    bstr_append_long(str, syserr);
       -    bstr_append(str, ": ");
       -    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
       -                  FORMAT_MESSAGE_FROM_SYSTEM, NULL, syserr,
       -                  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
       -                  (LPTSTR)&lpMsgBuf, 0, NULL);
       -    bstr_append(str, lpMsgBuf);
       -    LocalFree(lpMsgBuf);
       -  }
       -
       -  MessageBox(NULL, str->text, fatal ? "Fatal Error" : "Error",
       -             MB_OK | MB_ICONSTOP);
       -  if (fatal)
       -    ExitProcess(1);
       -}
       -
       -void AddInstFiles(char *filename, DWORD filesize, InstFiles **lastpt,
       -                  InstFiles **firstpt)
       -{
       -  InstFiles *newpt;
       -
       -  newpt = bmalloc(sizeof(InstFiles));
       -  if (*lastpt) {
       -    (*lastpt)->next = newpt;
       -  } else {
       -    *firstpt = newpt;
       -  }
       -  *lastpt = newpt;
       -  newpt->next = NULL;
       -  newpt->filename = filename;
       -  newpt->filesize = filesize;
       -}
       -
       -void AddInstLink(char *linkfile, char *origfile, char *args,
       -                 InstLink **lastpt, InstLink **firstpt)
       -{
       -  InstLink *newpt;
       -
       -  newpt = bmalloc(sizeof(InstLink));
       -  if (*lastpt) {
       -    (*lastpt)->next = newpt;
       -  } else {
       -    *firstpt = newpt;
       -  }
       -  *lastpt = newpt;
       -  newpt->next = NULL;
       -  newpt->linkfile = linkfile;
       -  newpt->origfile = origfile;
       -  newpt->args = args;
       -}
       -
       -void FreeLinkList(InstLink *linklist, BOOL freepts)
       -{
       -  InstLink *thispt, *nextpt;
       -
       -  thispt = linklist;
       -  while (thispt) {
       -    nextpt = thispt->next;
       -
       -    if (freepts) {
       -      bfree(thispt->linkfile);
       -      bfree(thispt->origfile);
       -      bfree(thispt->args);
       -    }
       -    bfree(thispt);
       -
       -    thispt = nextpt;
       -  }
       -}
       -
       -void FreeFileList(InstFiles *filelist, BOOL freepts)
       -{
       -  InstFiles *thispt, *nextpt;
       -
       -  thispt = filelist;
       -  while (thispt) {
       -    nextpt = thispt->next;
       -
       -    if (freepts)
       -      bfree(thispt->filename);
       -    bfree(thispt);
       -
       -    thispt = nextpt;
       -  }
       -}
       -
       -void AddServiceDetails(char *servicename, char *servicedisp,
       -                       char *servicedesc, char *serviceexe,
       -                       NTService **service)
       -{
       -  *service = bmalloc(sizeof(NTService));
       -  (*service)->name = servicename;
       -  (*service)->display = servicedisp;
       -  (*service)->description = servicedesc;
       -  (*service)->exe = serviceexe;
       -}
       -
       -void FreeServiceDetails(NTService *service, BOOL freepts)
       -{
       -  if (!service)
       -    return;
       -
       -  if (freepts) {
       -    bfree(service->name);
       -    bfree(service->display);
       -    bfree(service->description);
       -    bfree(service->exe);
       -  }
       -  bfree(service);
       -}
       -
       -void FreeInstData(InstData *idata, BOOL freepts)
       -{
       -  FreeFileList(idata->instfiles, freepts);
       -  FreeFileList(idata->extrafiles, freepts);
       -  FreeFileList(idata->keepfiles, freepts);
       -
       -  FreeLinkList(idata->startmenu, freepts);
       -  FreeLinkList(idata->desktop, freepts);
       -
       -  FreeServiceDetails(idata->service, freepts);
       -
       -  bfree(idata->product);
       -  bfree(idata->installdir);
       -  bfree(idata->startmenudir);
       -
       -  bfree(idata);
       -}
       -
       -void WriteInstFlags(HANDLE fout, InstFlags flags)
       -{
       -  DWORD bytes_written;
       -  char str[3];
       -
       -  str[0] = (char)flags;
       -  if (!WriteFile(fout, str, 1, &bytes_written, NULL)) {
       -    printf("Write error\n");
       -  }
       -}
       -
       -void WriteServiceDetails(HANDLE fout, NTService *service)
       -{
       -  DWORD bytes_written;
       -  char str[] = "";
       -
       -  if (!service) {
       -    if (!WriteFile(fout, str, strlen(str) + 1, &bytes_written, NULL)) {
       -      printf("Write error\n");
       -    }
       -  } else {
       -    if (!WriteFile(fout, service->name, strlen(service->name) + 1,
       -                   &bytes_written, NULL)) {
       -      printf("Write error\n");
       -    }
       -    if (!WriteFile(fout, service->display, strlen(service->display) + 1,
       -                   &bytes_written, NULL)) {
       -      printf("Write error\n");
       -    }
       -    if (!WriteFile
       -        (fout, service->description, strlen(service->description) + 1,
       -         &bytes_written, NULL)) {
       -      printf("Write error\n");
       -    }
       -    if (!WriteFile(fout, service->exe, strlen(service->exe) + 1,
       -                   &bytes_written, NULL)) {
       -      printf("Write error\n");
       -    }
       -  }
       -}
       -
       -void WriteLinkList(HANDLE fout, InstLink *listpt)
       -{
       -  char str[] = "";
       -  DWORD bytes_written;
       -
       -  for (; listpt; listpt = listpt->next) {
       -    if (!WriteFile(fout, listpt->linkfile, strlen(listpt->linkfile) + 1,
       -                   &bytes_written, NULL)) {
       -      printf("Write error\n");
       -    }
       -    if (!WriteFile(fout, listpt->origfile, strlen(listpt->origfile) + 1,
       -                   &bytes_written, NULL)) {
       -      printf("Write error\n");
       -    }
       -    if (!WriteFile(fout, listpt->args, strlen(listpt->args) + 1,
       -                   &bytes_written, NULL)) {
       -      printf("Write error\n");
       -    }
       -  }
       -  if (!WriteFile(fout, str, strlen(str) + 1, &bytes_written, NULL)) {
       -    printf("Write error\n");
       -  }
       -}
       -
       -void WriteFileList(HANDLE fout, InstFiles *listpt)
       -{
       -  bstr *str;
       -  DWORD bytes_written;
       -
       -  str = bstr_new();
       -
       -  for (; listpt; listpt = listpt->next) {
       -    if (!WriteFile(fout, listpt->filename, strlen(listpt->filename) + 1,
       -                   &bytes_written, NULL)) {
       -      printf("Write error\n");
       -    }
       -    bstr_setlength(str, 0);
       -    bstr_append_long(str, listpt->filesize);
       -    if (!WriteFile(fout, str->text, str->length + 1, &bytes_written, NULL)) {
       -      printf("Write error\n");
       -    }
       -  }
       -  bstr_assign(str, "");
       -  if (!WriteFile(fout, str->text, str->length + 1, &bytes_written, NULL)) {
       -    printf("Write error\n");
       -  }
       -  bstr_free(str, TRUE);
       -}
       -
       -static char *GetSpecialDir(int dirtype)
       -{
       -  LPITEMIDLIST pidl;
       -  LPMALLOC pmalloc;
       -  char szDir[MAX_PATH];
       -  BOOL doneOK = FALSE;
       -
       -  if (SUCCEEDED(SHGetMalloc(&pmalloc))) {
       -    if (SUCCEEDED(SHGetSpecialFolderLocation(NULL, dirtype, &pidl))) {
       -      if (SHGetPathFromIDList(pidl, szDir))
       -        doneOK = TRUE;
       -      pmalloc->lpVtbl->Free(pmalloc, pidl);
       -    }
       -    pmalloc->lpVtbl->Release(pmalloc);
       -  }
       -  return (doneOK ? bstrdup(szDir) : NULL);
       -}
       -
       -char *GetStartMenuTopDir(BOOL AllUsers)
       -{
       -  return GetSpecialDir(AllUsers ? CSIDL_COMMON_STARTMENU :
       -                       CSIDL_STARTMENU);
       -}
       -
       -char *GetDesktopDir(void)
       -{
       -  return GetSpecialDir(CSIDL_DESKTOPDIRECTORY);
       -}
       -
       -char *GetStartMenuDir(BOOL AllUsers, InstData *idata)
       -{
       -  bstr *str;
       -  char *topdir, *retval;
       -
       -  topdir = GetStartMenuTopDir(AllUsers);
       -
       -  str = bstr_new();
       -
       -  bstr_assign(str, topdir);
       -  bfree(topdir);
       -
       -  bstr_appendpath(str, "Programs");
       -  bstr_appendpath(str, idata->startmenudir);
       -
       -  retval = str->text;
       -  bstr_free(str, FALSE);
       -  return retval;
       -}
       -
       -BOOL CreateWholeDirectory(char *path)
       -{
       -  char *pt;
       -
       -  if (!path)
       -    return FALSE;
       -
       -  /* We may as well try the easy way first */
       -  if (CreateDirectory(path, NULL))
       -    return TRUE;
       -
       -  /* \\machine\share notation */
       -  if (strlen(path) > 2 && path[0] == '\\' && path[1] == '\\') {
       -    pt = &path[2];              /* Skip initial "\\" */
       -    while (*pt && *pt != '\\')
       -      pt++;                     /* Skip the machine name */
       -    /* X: notation */
       -  } else if (strlen(path) > 2 && path[1] == ':') {
       -    pt = &path[2];              /* Skip the X: part */
       -  } else {
       -    pt = path;
       -  }
       -
       -
       -  while (*pt) {
       -    pt++;
       -    if (*pt == '\\') {
       -      *pt = '\0';
       -      if (!CreateDirectory(path, NULL)
       -          && GetLastError() != ERROR_ALREADY_EXISTS) {
       -        *pt = '\\';
       -        return FALSE;
       -      }
       -      *pt = '\\';
       -    }
       -  }
       -  return (CreateDirectory(path, NULL)
       -          || GetLastError() == ERROR_ALREADY_EXISTS);
       -}
       -
       -BOOL RemoveWholeDirectory(char *path)
       -{
       -  char *pt;
       -  BOOL retval;
       -
       -  if (!path || !RemoveDirectory(path))
       -    return FALSE;
       -
       -  for (pt = &path[strlen(path) - 2]; pt > path; pt--) {
       -    if (*pt == '\\') {
       -      *pt = '\0';
       -      retval = RemoveDirectory(path);
       -      *pt = '\\';
       -      if (!retval)
       -        break;
       -    }
       -  }
       -  return TRUE;
       -}
       -
       -void RemoveService(NTService *service)
       -{
       -  SC_HANDLE scManager, scService;
       -  SERVICE_STATUS status;
       -
       -  if (!service)
       -    return;
       -
       -  scManager = OpenSCManager(NULL, NULL, GENERIC_READ);
       -
       -  if (!scManager) {
       -    DisplayError("Cannot connect to service manager", TRUE, FALSE);
       -    return;
       -  }
       -
       -  scService = OpenService(scManager, service->name, DELETE | SERVICE_STOP);
       -  if (!scService) {
       -    DisplayError("Cannot open service", TRUE, FALSE);
       -  } else {
       -    if (!ControlService(scService, SERVICE_CONTROL_STOP, &status) &&
       -        GetLastError() != ERROR_SERVICE_NOT_ACTIVE) {
       -      DisplayError("Cannot stop service", TRUE, FALSE);
       -    }
       -    if (!DeleteService(scService)) {
       -      DisplayError("Cannot delete service", TRUE, FALSE);
       -    }
       -    CloseServiceHandle(scService);
       -  }
       -
       -  CloseServiceHandle(scManager);
       -}
       -
       -char *read_line0(HANDLE hin)
       -{
       -  char *buf;
       -  int bufsize = 32, strind = 0;
       -  DWORD bytes_read;
       -
       -  buf = bmalloc(bufsize);
       -
       -  while (1) {
       -    if (!ReadFile(hin, &buf[strind], 1, &bytes_read, NULL)) {
       -      printf("Read error\n");
       -      break;
       -    }
       -    if (bytes_read == 0) {
       -      buf[strind] = '\0';
       -      break;
       -    } else if (buf[strind] == '\0')
       -      break;
       -    else {
       -      strind++;
       -      if (strind >= bufsize) {
       -        bufsize *= 2;
       -        buf = brealloc(buf, bufsize);
       -      }
       -    }
       -  }
       -  if (strind == 0) {
       -    bfree(buf);
       -    return NULL;
       -  } else
       -    return buf;
       -}
       -
       -InstLink *ReadLinkList(HANDLE fin)
       -{
       -  InstLink *first = NULL, *listpt = NULL, *newpt;
       -  char *linkfile, *origfile, *args;
       -
       -  while (1) {
       -    linkfile = read_line0(fin);
       -    if (!linkfile)
       -      break;
       -    origfile = read_line0(fin);
       -    args = read_line0(fin);
       -    if (!origfile)
       -      DisplayError("Corrupt install.log", FALSE, TRUE);
       -    newpt = bmalloc(sizeof(InstLink));
       -    if (listpt)
       -      listpt->next = newpt;
       -    else
       -      first = newpt;
       -    listpt = newpt;
       -    newpt->next = NULL;
       -    newpt->linkfile = linkfile;
       -    newpt->origfile = origfile;
       -    newpt->args = args;
       -  }
       -  return first;
       -}
       -
       -InstFlags ReadInstFlags(HANDLE fin)
       -{
       -  DWORD bytes_read;
       -  char buf[3];
       -
       -  buf[0] = 0;
       -  if (!ReadFile(fin, buf, 1, &bytes_read, NULL)) {
       -    printf("Read error\n");
       -  }
       -
       -  return (InstFlags)buf[0];
       -}
       -
       -NTService *ReadServiceDetails(HANDLE fin)
       -{
       -  NTService *service = NULL;
       -  char *name, *disp, *desc, *exe;
       -
       -  name = read_line0(fin);
       -  if (name) {
       -    disp = read_line0(fin);
       -    desc = read_line0(fin);
       -    exe = read_line0(fin);
       -    if (!disp || !desc || !exe) {
       -      DisplayError("Corrupt install.log", FALSE, TRUE);
       -    } else {
       -      AddServiceDetails(name, disp, desc, exe, &service);
       -    }
       -  }
       -
       -  return service;
       -}
       -
       -InstFiles *ReadFileList(HANDLE fin)
       -{
       -  InstFiles *first = NULL, *listpt = NULL, *newpt;
       -  char *filename, *filesize;
       -
       -  while (1) {
       -    filename = read_line0(fin);
       -    if (!filename)
       -      break;
       -    filesize = read_line0(fin);
       -    if (!filesize)
       -      DisplayError("Corrupt install.log", FALSE, TRUE);
       -    newpt = bmalloc(sizeof(InstFiles));
       -    if (listpt)
       -      listpt->next = newpt;
       -    else
       -      first = newpt;
       -    listpt = newpt;
       -
       -    newpt->next = NULL;
       -    newpt->filename = filename;
       -    newpt->filesize = atol(filesize);
       -    bfree(filesize);
       -  }
       -  return first;
       -}
       -
       -char *GetInstallDir(char *product)
       -{
       -  HKEY key;
       -  bstr *str;
       -  DWORD keytype, keylen;
       -  char *installdir;
       -
       -  str = bstr_new();
       -  bstr_assign(str, UninstallKey);
       -  bstr_appendpath(str, product);
       -  if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, str->text, 0,
       -                   KEY_ALL_ACCESS, &key) != ERROR_SUCCESS) {
       -    DisplayError("Could not open registry", FALSE, TRUE);
       -  }
       -
       -  if (RegQueryValueEx(key, "InstallDirectory", NULL,
       -                      &keytype, NULL, &keylen) != ERROR_SUCCESS ||
       -      keytype != REG_SZ) {
       -    DisplayError("Could not query registry key", FALSE, TRUE);
       -  }
       -
       -  installdir = bmalloc(keylen);
       -  if (RegQueryValueEx(key, "InstallDirectory", NULL,
       -                      &keytype, installdir, &keylen) != ERROR_SUCCESS) {
       -    DisplayError("Could not get registry key value", FALSE, TRUE);
       -  }
       -  RegCloseKey(key);
       -
       -  bstr_free(str, TRUE);
       -  return installdir;
       -}
       -
       -InstData *ReadOldInstData(HANDLE fin, char *product, char *installdir)
       -{
       -  InstData *idata;
       -
       -  idata = bmalloc(sizeof(InstData));
       -
       -  idata->product = product;
       -  idata->installdir = installdir;
       -  idata->startmenudir = read_line0(fin);
       -
       -  idata->instfiles = ReadFileList(fin);
       -  idata->extrafiles = ReadFileList(fin);
       -  idata->keepfiles = NULL;
       -
       -  idata->startmenu = ReadLinkList(fin);
       -  idata->desktop = ReadLinkList(fin);
       -
       -  idata->service = ReadServiceDetails(fin);
       -
       -  idata->flags = ReadInstFlags(fin);
       -
       -  return idata;
       -}
       -
       -void DeleteFileList(InstFiles *listpt, HWND hwnd, InstFiles *keepfiles)
       -{
       -  bstr *str;
       -  char *sep;
       -  InstFiles *keeppt;
       -
       -  str = bstr_new();
       -  for (; listpt; listpt = listpt->next) {
       -    keeppt = keepfiles;
       -    while (keeppt && strcmp(keeppt->filename, listpt->filename) != 0) {
       -      keeppt = keeppt->next;
       -    }
       -    if (keeppt) {
       -      keeppt->filesize = 1;     /* Mark that this file is already
       -                                 * installed */
       -    } else {
       -      bstr_assign(str, "Deleting file: ");
       -      bstr_append(str, listpt->filename);
       -      SendMessage(hwnd, WM_SETTEXT, 0, (LPARAM)str->text);
       -      DeleteFile(listpt->filename);
       -      sep = strrchr(listpt->filename, '\\');
       -      if (sep) {
       -        *sep = '\0';
       -        RemoveWholeDirectory(listpt->filename);
       -        *sep = '\\';
       -      }
       -    }
       -  }
       -  bstr_free(str, TRUE);
       -}
       -
       -void DeleteLinkList(char *dir, InstLink *listpt, HWND hwnd)
       -{
       -  bstr *str;
       -
       -  str = bstr_new();
       -  if (SetCurrentDirectory(dir)) {
       -    for (; listpt; listpt = listpt->next) {
       -      bstr_assign(str, "Deleting shortcut: ");
       -      bstr_append(str, listpt->linkfile);
       -      SendMessage(hwnd, WM_SETTEXT, 0, (LPARAM)str->text);
       -      DeleteFile(listpt->linkfile);
       -    }
       -  } else {
       -    bstr_assign(str, "Could not find shortcut directory ");
       -    bstr_append(str, dir);
       -    DisplayError(str->text, TRUE, FALSE);
       -  }
       -  bstr_free(str, TRUE);
       -}
       -
       -void RemoveUninstall(char *startmenu, char *product, BOOL delexe)
       -{
       -  bstr *inipath, *uninstpath, *uninstlink;
       -
       -  inipath = bstr_new();
       -  uninstpath = bstr_new();
       -  uninstlink = bstr_new();
       -
       -  bstr_assign(uninstlink, startmenu);
       -  bstr_appendpath(uninstlink, "Uninstall ");
       -  bstr_append(uninstlink, product);
       -  bstr_append(uninstlink, ".LNK");
       -  DeleteFile(uninstlink->text);
       -
       -  if (delexe) {
       -    bstr_assign_windir(inipath);
       -    bstr_assign(uninstpath, inipath->text);
       -
       -    bstr_appendpath(inipath, "wininit.ini");
       -    bstr_appendpath(uninstpath, UninstallEXE);
       -
       -    if (!WritePrivateProfileString("Renane", "NUL", uninstpath->text,
       -                                   inipath->text)) {
       -      DisplayError("Cannot write to wininit.ini: ", TRUE, FALSE);
       -    }
       -  }
       -
       -  bstr_free(uninstlink, TRUE);
       -  bstr_free(uninstpath, TRUE);
       -  bstr_free(inipath, TRUE);
       -}
 (DIR) diff --git a/win32/util.h b/win32/util.h
       t@@ -1,119 +0,0 @@
       -/************************************************************************
       - * util.h         Shared functions for Win32 installer programs         *
       - * Copyright (C)  2001-2004  Ben Webb                                   *
       - *                Email: benwebb@users.sf.net                           *
       - *                WWW: https://dopewars.sourceforge.io/                 *
       - *                                                                      *
       - * This program is free software; you can redistribute it and/or        *
       - * modify it under the terms of the GNU General Public License          *
       - * as published by the Free Software Foundation; either version 2       *
       - * of the License, or (at your option) any later version.               *
       - *                                                                      *
       - * This program is distributed in the hope that it will be useful,      *
       - * but WITHOUT ANY WARRANTY; without even the implied warranty of       *
       - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        *
       - * GNU General Public License for more details.                         *
       - *                                                                      *
       - * You should have received a copy of the GNU General Public License    *
       - * along with this program; if not, write to the Free Software          *
       - * Foundation, Inc., 59 Temple Place - Suite 330, Boston,               *
       - *                   MA  02111-1307, USA.                               *
       - ************************************************************************/
       -
       -#include <windows.h>
       -
       -typedef struct _bstr {
       -  char *text;
       -  unsigned length;              /* Length of current text, NOT including
       -                                 * terminating null */
       -  unsigned bufsiz;              /* Size of the allocated memory buffer */
       -} bstr;
       -
       -typedef struct _InstFiles {
       -  char *filename;
       -  DWORD filesize;
       -  struct _InstFiles *next;
       -} InstFiles;
       -
       -typedef struct _InstLink {
       -  char *linkfile;
       -  char *origfile;
       -  char *args;
       -  struct _InstLink *next;
       -} InstLink;
       -
       -typedef struct _NTService {
       -  char *name;
       -  char *display;
       -  char *description;
       -  char *exe;
       -} NTService;
       -
       -typedef enum {
       -  IF_ALLUSERS = 1
       -} InstFlags;
       -
       -typedef struct _InstData {
       -  char *product;
       -  char *installdir, *startmenudir;
       -  DWORD totalsize;
       -  NTService *service;
       -  InstFiles *instfiles;
       -  InstFiles *extrafiles;
       -  InstFiles *keepfiles;
       -  InstLink *startmenu;
       -  InstLink *desktop;
       -  InstFlags flags;
       -} InstData;
       -
       -extern const char *UninstallKey;
       -extern const char *UninstallEXE;
       -
       -void *bmalloc(UINT numbytes);
       -void bfree(void *pt);
       -void *brealloc(void *pt, UINT numbytes);
       -char *bstrdup(char *str);
       -
       -bstr *bstr_new(void);
       -void bstr_free(bstr *str, BOOL free_text);
       -void bstr_expandby(bstr *str, unsigned extralength);
       -void bstr_setlength(bstr *str, unsigned length);
       -void bstr_assign(bstr *str, const char *text);
       -void bstr_append(bstr *str, const char *text);
       -void bstr_appendpath(bstr *str, const char *text);
       -void bstr_append_c(bstr *str, const char ch);
       -void bstr_append_long(bstr *str, const long val);
       -void bstr_append_windir(bstr *str);
       -void bstr_append_curdir(bstr *str);
       -void bstr_assign_windir(bstr *str);
       -void bstr_assign_curdir(bstr *str);
       -void bstr_assign_progfilesdir(bstr *str);
       -void bstr_append_progfilesdir(bstr *str);
       -
       -void DisplayError(const char *errtext, BOOL addsyserr, BOOL fatal);
       -void AddInstFiles(char *filename, DWORD filesize, InstFiles **lastpt,
       -                  InstFiles **firstpt);
       -void AddInstLink(char *linkfile, char *origfile, char *args,
       -                 InstLink **lastpt, InstLink **firstpt);
       -void FreeLinkList(InstLink *linklist, BOOL freepts);
       -void FreeFileList(InstFiles *filelist, BOOL freepts);
       -void FreeInstData(InstData *idata, BOOL freepts);
       -void AddServiceDetails(char *servicename, char *servicedisp,
       -                       char *servicedesc, char *serviceexe,
       -                       NTService **service);
       -void FreeServiceDetails(NTService *service, BOOL freepts);
       -void WriteServiceDetails(HANDLE fout, NTService *service);
       -void WriteInstFlags(HANDLE fout, InstFlags flags);
       -void WriteLinkList(HANDLE fout, InstLink *listpt);
       -void WriteFileList(HANDLE fout, InstFiles *listpt);
       -char *GetStartMenuTopDir(BOOL AllUsers);
       -char *GetStartMenuDir(BOOL AllUsers, InstData *idata);
       -char *GetDesktopDir(void);
       -BOOL CreateWholeDirectory(char *path);
       -BOOL RemoveWholeDirectory(char *path);
       -void DeleteLinkList(char *dir, InstLink *listpt, HWND hwnd);
       -void DeleteFileList(InstFiles *listpt, HWND hwnd, InstFiles *keepfiles);
       -InstData *ReadOldInstData(HANDLE fin, char *product, char *installdir);
       -char *GetInstallDir(char *product);
       -void RemoveService(NTService *service);
       -void RemoveUninstall(char *startmenu, char *product, BOOL delexe);
 (DIR) diff --git a/win32/zlib/Makefile.nocygwin b/win32/zlib/Makefile.nocygwin
       t@@ -1,154 +0,0 @@
       -# Makefile for zlib
       -# Copyright (C) 1995-2003 Jean-loup Gailly.
       -# For conditions of distribution and use, see copyright notice in zlib.h
       -
       -# To compile and test, type:
       -#    ./configure; make test
       -# The call of configure is optional if you don't have special requirements
       -# If you wish to build zlib as a shared library, use: ./configure -s
       -
       -# To use the asm code, type:
       -#    cp contrib/asm?86/match.S ./match.S
       -#    make LOC=-DASMV OBJA=match.o
       -
       -# To install /usr/local/lib/libz.* and /usr/local/include/zlib.h, type:
       -#    make install
       -# To install in $HOME instead of /usr/local, use:
       -#    make install prefix=$HOME
       -
       -CC=cc -mno-cygwin
       -
       -CFLAGS=-O
       -#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
       -#CFLAGS=-g -DDEBUG
       -#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
       -#           -Wstrict-prototypes -Wmissing-prototypes
       -
       -LDFLAGS=libz.a
       -LDSHARED=$(CC)
       -CPP=$(CC) -E
       -
       -LIBS=libz.a
       -SHAREDLIB=libz.so
       -SHAREDLIBV=libz.so.1.2.1
       -SHAREDLIBM=libz.so.1
       -
       -AR=ar rc
       -RANLIB=ranlib
       -TAR=tar
       -SHELL=/bin/sh
       -EXE=
       -
       -prefix = /usr/local
       -exec_prefix = ${prefix}
       -libdir = ${exec_prefix}/lib
       -includedir = ${prefix}/include
       -mandir = ${prefix}/share/man
       -man3dir = ${mandir}/man3
       -
       -OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \
       -       zutil.o inflate.o infback.o inftrees.o inffast.o
       -
       -OBJA =
       -# to use the asm code: make OBJA=match.o
       -
       -TEST_OBJS = example.o minigzip.o
       -
       -all: example$(EXE) minigzip$(EXE)
       -
       -check: test
       -test: all
       -        @LD_LIBRARY_PATH=.:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \
       -        echo hello world | ./minigzip | ./minigzip -d || \
       -          echo '                *** minigzip test FAILED ***' ; \
       -        if ./example; then \
       -          echo '                *** zlib test OK ***'; \
       -        else \
       -          echo '                *** zlib test FAILED ***'; \
       -        fi
       -
       -libz.a: $(OBJS) $(OBJA)
       -        $(AR) $@ $(OBJS) $(OBJA)
       -        -@ ($(RANLIB) $@ || true) >/dev/null 2>&1
       -
       -match.o: match.S
       -        $(CPP) match.S > _match.s
       -        $(CC) -c _match.s
       -        mv _match.o match.o
       -        rm -f _match.s
       -
       -$(SHAREDLIBV): $(OBJS)
       -        $(LDSHARED) -o $@ $(OBJS)
       -        rm -f $(SHAREDLIB) $(SHAREDLIBM)
       -        ln -s $@ $(SHAREDLIB)
       -        ln -s $@ $(SHAREDLIBM)
       -
       -example$(EXE): example.o $(LIBS)
       -        $(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS)
       -
       -minigzip$(EXE): minigzip.o $(LIBS)
       -        $(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS)
       -
       -install: $(LIBS)
       -        -@if [ ! -d $(exec_prefix) ]; then mkdir -p $(exec_prefix); fi
       -        -@if [ ! -d $(includedir)  ]; then mkdir -p $(includedir); fi
       -        -@if [ ! -d $(libdir)      ]; then mkdir -p $(libdir); fi
       -        -@if [ ! -d $(man3dir)     ]; then mkdir -p $(man3dir); fi
       -        cp zlib.h zconf.h $(includedir)
       -        chmod 644 $(includedir)/zlib.h $(includedir)/zconf.h
       -        cp $(LIBS) $(libdir)
       -        cd $(libdir); chmod 755 $(LIBS)
       -        -@(cd $(libdir); $(RANLIB) libz.a || true) >/dev/null 2>&1
       -        cd $(libdir); if test -f $(SHAREDLIBV); then \
       -          rm -f $(SHAREDLIB) $(SHAREDLIBM); \
       -          ln -s $(SHAREDLIBV) $(SHAREDLIB); \
       -          ln -s $(SHAREDLIBV) $(SHAREDLIBM); \
       -          (ldconfig || true)  >/dev/null 2>&1; \
       -        fi
       -        cp zlib.3 $(man3dir)
       -        chmod 644 $(man3dir)/zlib.3
       -# The ranlib in install is needed on NeXTSTEP which checks file times
       -# ldconfig is for Linux
       -
       -uninstall:
       -        cd $(includedir); \
       -        cd $(libdir); rm -f libz.a; \
       -        if test -f $(SHAREDLIBV); then \
       -          rm -f $(SHAREDLIBV) $(SHAREDLIB) $(SHAREDLIBM); \
       -        fi
       -        cd $(man3dir); rm -f zlib.3
       -
       -mostlyclean: clean
       -clean:
       -        rm -f *.o *~ example$(EXE) minigzip$(EXE) \
       -           libz.* foo.gz so_locations \
       -           _match.s maketree contrib/infback9/*.o
       -
       -maintainer-clean: distclean
       -distclean: clean
       -        cp -p Makefile.in Makefile
       -        cp -p zconf.in.h zconf.h
       -        rm -f .DS_Store
       -
       -tags:
       -        etags *.[ch]
       -
       -depend:
       -        makedepend -- $(CFLAGS) -- *.[ch]
       -
       -# DO NOT DELETE THIS LINE -- make depend depends on it.
       -
       -adler32.o: zlib.h zconf.h
       -compress.o: zlib.h zconf.h
       -crc32.o: crc32.h zlib.h zconf.h
       -deflate.o: deflate.h zutil.h zlib.h zconf.h
       -example.o: zlib.h zconf.h
       -gzio.o: zutil.h zlib.h zconf.h
       -inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
       -inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
       -infback.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
       -inftrees.o: zutil.h zlib.h zconf.h inftrees.h
       -minigzip.o: zlib.h zconf.h
       -trees.o: deflate.h zutil.h zlib.h zconf.h trees.h
       -uncompr.o: zlib.h zconf.h
       -zutil.o: zutil.h zlib.h zconf.h
 (DIR) diff --git a/win32/zlib/README.zlib b/win32/zlib/README.zlib
       t@@ -1,6 +0,0 @@
       -If you are intending to build the Win32 installer for dopewars, then place
       -the zlib distribution into this directory. The installer expects to
       -statically link with the file libz.a in this directory; the libz.a file
       -included in the Cygwin distribution should _not_ be used, as this requires
       -the CYGWIN.DLL file, which is not a standard Windows DLL. Use the
       -Makefile.nocygwin file to compile zlib, as this adds in the -mno-cygwin flag.