tWin32 installer now installs locale files and NT Service - 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 b07a0994d9818454a7d2184a9fa9b06932e348e9
(DIR) parent f352a9079a7907f5d1aed2befaa77dc2eeb4b5a5
(HTM) Author: Ben Webb <ben@salilab.org>
Date: Wed, 7 Nov 2001 18:43:54 +0000
Win32 installer now installs locale files and NT Service
Diffstat:
M TODO | 1 +
M src/winmain.c | 8 ++++++--
M win32/Makefile | 4 +++-
M win32/dialogs.rc | 4 ++--
M win32/filelist | 49 ++++++++++++++++---------------
M win32/makeinstall.c | 25 ++++++++++++++++---------
M win32/setup.c | 83 ++++++++++++++++++++++++-------
M win32/uninstall.c | 40 +++++++++++++++++++++++++++++++
M win32/util.c | 9 ++++++---
9 files changed, 165 insertions(+), 58 deletions(-)
---
(DIR) diff --git a/TODO b/TODO
t@@ -1,3 +1,4 @@
+- Make Windows installer deal with old installed versions properly
- Make server run as an NT Service
- Configuration file editor thingy in the client?
- Make minimize-to-systray code a) more robust and b) configurable
(DIR) diff --git a/src/winmain.c b/src/winmain.c
t@@ -167,10 +167,14 @@ int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,
LogFileStart();
g_set_print_handler(LogFilePrintFunc);
- g_log_set_handler(NULL,LogMask()|G_LOG_LEVEL_MESSAGE|G_LOG_LEVEL_WARNING|
- G_LOG_LEVEL_CRITICAL,
+ g_log_set_handler(NULL,LogMask()|G_LOG_LEVEL_MESSAGE,
ServerLogMessage,NULL);
+ if (!is_service) {
+ g_log_set_handler(NULL,G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL,
+ LogMessage,NULL);
+ }
+
#ifdef ENABLE_NLS
winlocale=GetWindowsLocale();
if (winlocale) putenv(winlocale);
(DIR) diff --git a/win32/Makefile b/win32/Makefile
t@@ -3,7 +3,6 @@ all: setup makeinstall uninstall
clean:
/bin/rm -f *.o *.res uninstall.exe setup.exe makeinstall.exe core *~
/bin/rm -f installfiles.gz manifest
- touch installfiles.gz manifest
setup: setup.o util.o guifunc.o setup.res
gcc -Wall -mno-cygwin -mwindows -o setup setup.o util.o guifunc.o setup.res zlib/libz.a -lcomctl32 -lole32 -luuid
t@@ -28,6 +27,9 @@ util.o: util.c util.h
guifunc.o: guifunc.c guifunc.h
gcc -Wall -mno-cygwin -c guifunc.c
+manifest installfiles.gz: filelist makeinstall uninstall
+ ./makeinstall
+
setup.res: setup.rc dialogs.rc contid.h manifest installfiles.gz
windres -O coff -o setup.res setup.rc
(DIR) diff --git a/win32/dialogs.rc b/win32/dialogs.rc
t@@ -1,13 +1,13 @@
#include "contid.h"
1 DIALOG 17, 40, 239, 162
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "dopewars-1.5.2 installation"
+CAPTION "dopewars-1.5.3 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.2 installation program.\nThis program will install dopewars-1.5.2 on your computer.", -1, 22, 14, 195, 17, WS_CHILD | WS_VISIBLE | WS_GROUP
+ LTEXT "Welcome to the dopewars-1.5.3 installation program.\nThis program will install dopewars-1.5.3 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, 51, 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, 94, 195, 18, WS_CHILD | WS_VISIBLE | WS_GROUP
END
(DIR) diff --git a/win32/filelist b/win32/filelist
t@@ -11,37 +11,38 @@ Server for the drug-dealing game "dopewars"
dopewars.exe -N
[install]
-licence.txt
-aiplayer.html
-clientplay.html
-commandline.html
-configfile.html
-credits.html
-developer.html
-i18n.html
-index.html
-installation.html
-metaserver.html
-server.html
-servercommands.html
-windows.html
-dopewars-config.txt
-dopewars.exe
-example-cfg.txt
-glib-1.3.dll
-readme.txt
+../../auxdope/licence.txt -> licence.txt
uninstall.exe
-locale/de/LC_MESSAGES/dopewars.mo
-locale/pl/LC_MESSAGES/dopewars.mo
-locale/pt_BR/LC_MESSAGES/dopewars.mo
-locale/fr/LC_MESSAGES/dopewars.mo
+../doc/aiplayer.html -> aiplayer.html
+../doc/clientplay.html -> clientplay.html
+../doc/commandline.html -> commandline.html
+../doc/configfile.html -> configfile.html
+../doc/credits.html -> credits.html
+../doc/developer.html -> developer.html
+../doc/i18n.html -> i18n.html
+../doc/index.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
+../../auxdope/dopewars-config.txt -> dopewars-config.txt
+../src/dopewars.exe -> dopewars.exe
+../../auxdope/example-cfg.txt -> example-cfg.txt
+../../auxdope/glib-1.3.dll -> glib-1.3.dll
+../../auxdope/readme.txt -> readme.txt
+../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/pt_BR.gmo -> locale\pt_BR\LC_MESSAGES\dopewars.mo
[extrafiles]
dopewars-log.txt
dopewars.sco
[startmenudir]
-dopewars-1.5.2
+dopewars-1.5.3
[startmenu]
dopewars.lnk
(DIR) diff --git a/win32/makeinstall.c b/win32/makeinstall.c
t@@ -20,7 +20,7 @@
#include <windows.h>
#include <stdio.h>
-#include <zlib.h>
+#include "zlib/zlib.h"
#include "util.h"
char *read_line(HANDLE hin) {
t@@ -57,12 +57,12 @@ InstData *ReadInstallData() {
int i;
enum {
S_PRODUCT=0,S_INSTDIR,S_INSTALL,S_EXTRA,S_STARTMENUDIR,
- S_STARTMENU,S_DESKTOP,
+ S_STARTMENU,S_DESKTOP,S_NTSERVICE,
S_NONE
} section=S_NONE;
char *titles[S_NONE] = {
"[product]","[instdir]", "[install]","[extrafiles]","[startmenudir]",
- "[startmenu]","[desktop]"
+ "[startmenu]","[desktop]","[NT Service]"
};
idata = bmalloc(sizeof(InstData));
t@@ -72,7 +72,7 @@ InstData *ReadInstallData() {
fin = CreateFile("filelist",GENERIC_READ,0,NULL,OPEN_EXISTING,0,NULL);
- if (fin) {
+ if (fin!=INVALID_HANDLE_VALUE) {
while (1) {
line=read_line(fin);
if (!line) break;
t@@ -130,14 +130,21 @@ printf("desktop entry = %s/%s/%s\n",line,line2,line3);
#define COMPRESSION Z_BEST_COMPRESSION
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) *fin = CreateFile((*listpt)->filename,GENERIC_READ,0,NULL,
- OPEN_EXISTING,0,NULL);
+ 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() {
t@@ -169,9 +176,9 @@ int main() {
filept=NULL;
fin=NULL;
OpenNextFile(idata->instfiles,&filept,&fin);
- if (!fin) { printf("Cannot open file\n"); return 1; }
+ if (fin==INVALID_HANDLE_VALUE) { return 1; }
- while (fin) {
+ while (fin!=INVALID_HANDLE_VALUE) {
if (z.avail_in==0) {
z.next_in = inbuf;
bytes_read=0;
t@@ -210,7 +217,7 @@ int main() {
fout = CreateFile("manifest",GENERIC_WRITE,0,NULL,
CREATE_ALWAYS,0,NULL);
- if (!fout) printf("Cannot create file list\n");
+ if (fout==INVALID_HANDLE_VALUE) printf("Cannot create file list\n");
str=bstr_new();
bstr_setlength(str,0);
(DIR) diff --git a/win32/setup.c b/win32/setup.c
t@@ -23,7 +23,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <zlib.h>
+#include "zlib/zlib.h"
#include <shlobj.h>
#include "contid.h"
t@@ -43,6 +43,50 @@ HINSTANCE hInst=NULL;
DWORD WINAPI DoInstall(LPVOID lpParam);
static void GetWinText(char **text,HWND hWnd);
+void InstallService(void) {
+ SC_HANDLE scManager,scService;
+ HKEY key;
+ bstr *str;
+ static char keyprefix[] = "SYSTEM\\ControlSet001\\Services\\";
+
+ static char servicename[] = "dopewars-server";
+ static char servicedisp[] = "dopewars server";
+ static char serviceexe[] = "dopewars.exe -N";
+ static char servicedesc[] = "Server for the drug-dealing game \"dopewars\"";
+
+ scManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
+
+ if (!scManager) {
+ DisplayError("Cannot connect to service manager",TRUE,FALSE);
+ return;
+ }
+
+ str = bstr_new();
+ bstr_assign(str,idata->installdir);
+ bstr_appendpath(str,serviceexe);
+
+ scService = CreateService(scManager,servicename,servicedisp,
+ 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;
+ }
+
+ bstr_assign(str,keyprefix);
+ bstr_append(str,servicename);
+ if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,str->text,0,KEY_WRITE,&key)
+ ==ERROR_SUCCESS) {
+ RegSetValueEx(key,"Description",0,REG_SZ,servicedesc,strlen(servicedesc));
+ RegCloseKey(key);
+ }
+
+ CloseServiceHandle(scService);
+ CloseServiceHandle(scManager);
+}
+
BOOL CheckCreateDir(void) {
/* Checks that the install directory exists, and creates it if it does not.
Returns TRUE if the directory is OK. */
t@@ -309,11 +353,12 @@ char *GetFirstFile(InstFiles *filelist,DWORD totalsize) {
BOOL OpenNextOutput(HANDLE *fout,InstFiles *filelist,InstFiles **listpt,
DWORD *fileleft,HANDLE logf) {
+ char *filename,*sep;
bstr *str;
DWORD bytes_written;
if (*fout) CloseHandle(*fout);
- *fout = NULL;
+ *fout = INVALID_HANDLE_VALUE;
str=bstr_new();
t@@ -332,21 +377,32 @@ BOOL OpenNextOutput(HANDLE *fout,InstFiles *filelist,InstFiles **listpt,
} else *listpt = filelist;
if (*listpt) {
- *fout = CreateFile((*listpt)->filename,GENERIC_WRITE,0,NULL,
- CREATE_ALWAYS,0,NULL);
+ filename = (*listpt)->filename;
+ sep = strrchr(filename,'\\');
+ if (sep) {
+ *sep = '\0';
+ CreateWholeDirectory(filename);
+ *sep = '\\';
+ }
+ *fout = CreateFile(filename,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,0,NULL);
*fileleft = (*listpt)->filesize;
bstr_assign(str,"Installing file: ");
- bstr_append(str,(*listpt)->filename);
+ 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);
+ }
}
bstr_free(str,TRUE);
- return (*fout!=NULL);
+ return (*fout!=INVALID_HANDLE_VALUE);
}
HRESULT CreateLink(LPCSTR origPath,LPSTR linkArgs,LPSTR workDir,
t@@ -408,15 +464,6 @@ void CreateLinks(char *linkdir,InstLink *linkpt) {
CreateLink(origfile->text,linkpt->args,idata->installdir,
linkpath->text,NULL);
-
-/*bstr_append_c(origfile,',');
-bstr_append(origfile,linkpt->args);
-bstr_append_c(origfile,',');
-bstr_append(origfile,idata->installdir);
-bstr_append_c(origfile,',');
-bstr_append(origfile,linkpath->text);
-bstr_append(origfile,", NULL");
-MessageBox(NULL,origfile->text,NULL,MB_OK);*/
}
}
t@@ -539,7 +586,7 @@ DWORD WINAPI DoInstall(LPVOID lpParam) {
printf("Write error\n");
}
- fout = NULL;
+ fout = INVALID_HANDLE_VALUE;
listpt=NULL;
OpenNextOutput(&fout,idata->instfiles,&listpt,&fileleft,logf);
t@@ -570,7 +617,7 @@ DWORD WINAPI DoInstall(LPVOID lpParam) {
if (!OpenNextOutput(&fout,idata->instfiles,&listpt,
&fileleft,logf)) break;
}
- if (!fout) break;
+ if (fout==INVALID_HANDLE_VALUE) break;
if (count && !WriteFile(fout,z.next_out,count,&bytes_written,NULL)) {
printf("Write error\n");
}
t@@ -592,6 +639,8 @@ DWORD WINAPI DoInstall(LPVOID lpParam) {
WriteFileList(logf,idata->extrafiles);
+ InstallService();
+
CoInitialize(NULL);
SetupShortcuts(logf);
SetupUninstall();
(DIR) diff --git a/win32/uninstall.c b/win32/uninstall.c
t@@ -30,6 +30,35 @@ HINSTANCE hInst;
HWND mainDlg;
char *product;
+void RemoveService(void) {
+ SC_HANDLE scManager,scService;
+ SERVICE_STATUS status;
+ static char servicename[] = "dopewars-server";
+
+ scManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
+
+ if (!scManager) {
+ DisplayError("Cannot connect to service manager",TRUE,FALSE);
+ return;
+ }
+
+ scService = OpenService(scManager,servicename,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;
t@@ -157,12 +186,20 @@ InstData *ReadInstData(HANDLE fin,char *product,char *installdir) {
void DeleteFileList(InstFiles *listpt) {
bstr *str;
+ char *sep;
+
str=bstr_new();
for (;listpt;listpt=listpt->next) {
bstr_assign(str,"Deleting file: ");
bstr_append(str,listpt->filename);
SendDlgItemMessage(mainDlg,ST_DELSTAT,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);
}
t@@ -235,6 +272,9 @@ DWORD WINAPI DoUninstall(LPVOID lpParam) {
if (fin) {
idata = ReadInstData(fin,product,installdir);
CloseHandle(fin);
+
+ RemoveService();
+
DeleteFile("install.log");
DeleteFileList(idata->instfiles);
DeleteFileList(idata->extrafiles);
(DIR) diff --git a/win32/util.c b/win32/util.c
t@@ -396,23 +396,26 @@ BOOL CreateWholeDirectory(char *path) {
/* \\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!='\\') pt++; /* Skip the first (root) '\' */
while (*pt) {
pt++;
if (*pt=='\\') {
*pt='\0';
- if (!CreateDirectory(path,NULL)) {
+ if (!CreateDirectory(path,NULL) && GetLastError()!=ERROR_ALREADY_EXISTS) {
*pt='\\'; return FALSE;
}
*pt='\\';
}
}
- return CreateDirectory(path,NULL);
+ return (CreateDirectory(path,NULL) || GetLastError()==ERROR_ALREADY_EXISTS);
}
BOOL RemoveWholeDirectory(char *path) {