tWin32 installer now installs locale files and NT Service - vaccinewars - be a … | |
git clone git://src.adamsgaard.dk/vaccinewars | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit b07a0994d9818454a7d2184a9fa9b06932e348e9 | |
parent f352a9079a7907f5d1aed2befaa77dc2eeb4b5a5 | |
Author: Ben Webb <[email protected]> | |
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(-) | |
--- | |
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 | |
diff --git a/src/winmain.c b/src/winmain.c | |
t@@ -167,10 +167,14 @@ int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrev… | |
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); | |
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 setu… | |
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 | |
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_VI… | |
PUSHBUTTON "&Next >", BT_NEXT, 144, 143, 39, 13, WS_CHILD | WS_VISIBLE… | |
PUSHBUTTON "Cancel", BT_CANCEL, 191, 143, 39, 13, WS_CHILD | WS_VISIBL… | |
- LTEXT "Welcome to the dopewars-1.5.2 installation program.\nThis progr… | |
+ LTEXT "Welcome to the dopewars-1.5.3 installation program.\nThis progr… | |
LTEXT "Use the ""Back"" and ""Next"" buttons at the bottom of the dial… | |
LTEXT "Newer versions of this program, when available, can be obtained… | |
END | |
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 | |
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); | |
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,Ins… | |
} 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(); | |
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 *in… | |
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); | |
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) { |