tCheck for admin rights added to Win32 installer; error handling cleaned up; option to install in user's own Start Menu or the "all users" Start Menu added - 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 ed7fb9cd1a09f667ebc6fb3fcd07a684bca1d1aa
(DIR) parent dc982dd81a76f2a8fcc599bdfe23552a230638de
(HTM) Author: Ben Webb <ben@salilab.org>
Date: Sun, 3 Feb 2002 20:20:07 +0000
Check for admin rights added to Win32 installer; error handling cleaned up;
option to install in user's own Start Menu or the "all users" Start Menu added
Diffstat:
M ChangeLog | 1 +
M TODO | 1 -
M win32/contid.h | 2 ++
M win32/dialogs.rc | 6 ++++--
M win32/setup.c | 143 +++++++++++++++++++++++--------
M win32/uninstall.c | 2 +-
M win32/util.c | 34 ++++++++++++++++++++++++++-----
M win32/util.h | 10 ++++++++--
8 files changed, 154 insertions(+), 45 deletions(-)
---
(DIR) diff --git a/ChangeLog b/ChangeLog
t@@ -12,6 +12,7 @@ cvs
- Keyboard shortcuts for menu items in Windows client
- Default buttons (ENTER -> "OK") for Windows client
- RPM build/make install can now be run as non-superuser
+ - Win32 install for current user/all users
- Code cleanups
1.5.2 16-10-2001
(DIR) diff --git a/TODO b/TODO
t@@ -1,4 +1,3 @@
-- Win32 install for current user/all users
- Test code under Win98
- Document new server interface
- Admin of running NT Service servers
(DIR) diff --git a/win32/contid.h b/win32/contid.h
t@@ -14,3 +14,5 @@
#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@@ -8,8 +8,10 @@ BEGIN
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.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
+ 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 ¤t 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
(DIR) diff --git a/win32/setup.c b/win32/setup.c
t@@ -40,24 +40,31 @@ 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);
-/* Returns TRUE if this operating system version supports NT Services */
-BOOL ServicesSupported(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_CONNECT);
+ scManager = OpenSCManager(NULL,NULL,SC_MANAGER_CREATE_SERVICE);
if (scManager) {
+ *hasServices = *isAdmin = TRUE;
CloseServiceHandle(scManager);
} else if (GetLastError()==ERROR_CALL_NOT_IMPLEMENTED) {
- return FALSE;
+ *hasServices = *isAdmin = FALSE;
+ } else {
+ *hasServices = TRUE;
+ *isAdmin = FALSE;
}
- return TRUE;
}
-void InstallService(InstData *idata) {
+BOOL InstallService(InstData *idata) {
SC_HANDLE scManager,scService;
HKEY key;
bstr *str;
t@@ -65,13 +72,13 @@ void InstallService(InstData *idata) {
NTService *service;
service = idata->service;
- if (!service) return;
+ if (!service) return FALSE;
- scManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
+ scManager = OpenSCManager(NULL,NULL,SC_MANAGER_CREATE_SERVICE);
if (!scManager) {
DisplayError("Cannot connect to service manager",TRUE,FALSE);
- return;
+ return FALSE;
}
str = bstr_new();
t@@ -85,7 +92,7 @@ void InstallService(InstData *idata) {
if (!scService) {
DisplayError("Cannot create service",TRUE,FALSE);
bstr_free(str,TRUE);
- return;
+ return FALSE;
}
bstr_assign(str,keyprefix);
t@@ -99,6 +106,7 @@ void InstallService(InstData *idata) {
CloseServiceHandle(scService);
CloseServiceHandle(scManager);
+ return TRUE;
}
BOOL CheckCreateDir(void) {
t@@ -117,7 +125,7 @@ BOOL CheckCreateDir(void) {
if (CreateWholeDirectory(instdir)) {
return TRUE;
} else {
- DisplayError("Could not create directory",FALSE,FALSE);
+ DisplayError("Could not create directory",TRUE,FALSE);
}
}
return FALSE;
t@@ -132,8 +140,20 @@ void ShowNewDialog(DialogType NewDialog) {
DWORD threadID;
if (NewDialog<0 || NewDialog>=DL_NUM) return;
- if (NewDialog > CurrentDialog && CurrentDialog==DL_INSTALLDIR) {
- if (!CheckCreateDir()) 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];
t@@ -253,13 +273,13 @@ LPVOID GetResource(LPCTSTR resname,LPCTSTR restype) {
LPVOID respt;
hrsrc = FindResource(NULL,resname,restype);
- if (!hrsrc) DisplayError("Could not find resource: ",TRUE,TRUE);
+ if (!hrsrc) DisplayError("Could not find resource",TRUE,TRUE);
hglobal = LoadResource(NULL,hrsrc);
- if (!hglobal) DisplayError("Could not load resource: ",TRUE,TRUE);
+ if (!hglobal) DisplayError("Could not load resource",TRUE,TRUE);
respt = LockResource(hglobal);
- if (!respt) DisplayError("Could not lock resource: ",TRUE,TRUE);
+ if (!respt) DisplayError("Could not lock resource",TRUE,TRUE);
return respt;
}
t@@ -277,6 +297,7 @@ InstData *ReadInstData() {
pt=instdata;
idata = bmalloc(sizeof(InstData));
+ idata->flags = 0;
idata->service = NULL;
idata->totalsize = atol(pt);
pt += strlen(pt)+1;
t@@ -515,16 +536,19 @@ void SetupShortcuts(HANDLE fout) {
char *startmenu,*desktop;
BOOL dodesktop;
- startmenu = GetStartMenuDir(idata);
+ startmenu = GetStartMenuDir(install_all_users, idata);
desktop = GetDesktopDir();
dodesktop=(IsDlgButtonChecked(mainDlg[DL_SHORTCUTS],CB_DESKTOP)==BST_CHECKED);
if (startmenu) {
- CreateDirectory(startmenu,NULL);
-
- CreateLinks(startmenu,idata->startmenu);
- WriteLinkList(fout,idata->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);
}
t@@ -564,7 +588,7 @@ void SetupUninstall() {
bstr_appendpath(str,idata->product);
if (RegCreateKeyEx(HKEY_LOCAL_MACHINE,str->text,0,NULL,0,
- KEY_ALL_ACCESS,NULL,&key,&disp)==ERROR_SUCCESS) {
+ KEY_WRITE,NULL,&key,&disp)==ERROR_SUCCESS) {
RegSetValueEx(key,"DisplayName",0,REG_SZ,idata->product,
strlen(idata->product));
bstr_assign_windir(str);
t@@ -576,7 +600,7 @@ void SetupUninstall() {
RegSetValueEx(key,"InstallDirectory",0,REG_SZ,str->text,str->length);
RegCloseKey(key);
} else {
- DisplayError("Cannot create registry key: ",TRUE,FALSE);
+ DisplayError("Cannot create registry key for uninstall",TRUE,FALSE);
}
bstr_assign_windir(str);
t@@ -587,11 +611,11 @@ void SetupUninstall() {
bstr_appendpath(uninstexe,"uninstall.exe");
if (!MoveFile(uninstexe->text,str->text)) {
- DisplayError("Unable to create uninstall program: ",TRUE,FALSE);
+ DisplayError("Unable to create uninstall program",TRUE,FALSE);
}
DeleteFile(uninstexe->text);
- startmenu = GetStartMenuDir(idata);
+ startmenu = GetStartMenuDir(install_all_users, idata);
bstr_assign(link,startmenu);
bstr_appendpath(link,"Uninstall ");
bstr_append(link,idata->product);
t@@ -636,7 +660,7 @@ void StartRemoveOldVersion(char *oldversion,InstData *idata,
DeleteFileList(old->instfiles,hwnd,idata->keepfiles);
DeleteFileList(old->extrafiles,hwnd,idata->keepfiles);
- startmenu = GetStartMenuDir(old);
+ startmenu = GetStartMenuDir(old->flags & IF_ALLUSERS, old);
desktop = GetDesktopDir();
DeleteLinkList(startmenu,old->startmenu,hwnd);
DeleteLinkList(desktop,old->desktop,hwnd);
t@@ -682,7 +706,7 @@ void FinishRemoveOldVersion(char *oldversion,InstData *idata,
if (strcmp(idata->startmenudir,oldidata->startmenudir)!=0) {
SetCurrentDirectory(desktop); /* Make sure we're not in the menu dir */
- startmenu = GetStartMenuDir(oldidata);
+ 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);
t@@ -707,7 +731,7 @@ void FinishRemoveOldVersion(char *oldversion,InstData *idata,
DWORD WINAPI DoInstall(LPVOID lpParam) {
HANDLE fout,logf,fin;
DWORD bytes_written,fileleft;
- BOOL skipfile;
+ BOOL skipfile, service_installed;
char *inbuf,*outbuf;
int status,count;
z_stream z;
t@@ -807,14 +831,34 @@ DWORD WINAPI DoInstall(LPVOID lpParam) {
FinishRemoveOldVersion(oldversion,idata,oldidata);
- InstallService(idata);
+ 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_OK);
+ }
CoInitialize(NULL);
SetupShortcuts(logf);
SetupUninstall();
CoUninitialize();
- WriteServiceDetails(logf,idata->service);
+ WriteServiceDetails(logf,service_installed ? idata->service : NULL);
+
+ if (install_all_users) {
+ idata->flags |= IF_ALLUSERS;
+ }
+ WriteInstFlags(logf, idata->flags);
CloseHandle(logf);
t@@ -836,9 +880,11 @@ void FillFolderList(void) {
folderlist = GetDlgItem(mainDlg[DL_SHORTCUTS],LB_FOLDLIST);
if (!folderlist) return;
+ SendMessage(folderlist,LB_RESETCONTENT,0,0);
+
str=bstr_new();
- startdir=GetStartMenuTopDir();
+ startdir=GetStartMenuTopDir(install_all_users);
bstr_assign(str,startdir);
bfree(startdir);
bstr_appendpath(str,"Programs\\*");
t@@ -858,6 +904,17 @@ void FillFolderList(void) {
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;
t@@ -924,6 +981,22 @@ BOOL CheckExistingInstall(InstData *idata) {
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;
t@@ -941,11 +1014,13 @@ int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,
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);
- FillFolderList();
-
ShowWindow(GetDlgItem(mainDlg[DL_DOINSTALL],ST_COMPLETE),SW_HIDE);
ShowWindow(GetDlgItem(mainDlg[DL_DOINSTALL],ST_EXIT),SW_HIDE);
t@@ -966,7 +1041,7 @@ int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,
for (i=0;i<DL_NUM;i++) SetGuiFont(mainDlg[i]);
- if (CheckExistingInstall(idata)) {
+ if (CheckAdminRights() && CheckExistingInstall(idata)) {
CurrentDialog=DL_NUM;
ShowNewDialog(DL_INTRO);
(DIR) diff --git a/win32/uninstall.c b/win32/uninstall.c
t@@ -70,7 +70,7 @@ DWORD WINAPI DoUninstall(LPVOID lpParam) {
DeleteFileList(idata->instfiles,delstat,NULL);
DeleteFileList(idata->extrafiles,delstat,NULL);
- startmenu = GetStartMenuDir(idata);
+ startmenu = GetStartMenuDir(idata->flags & IF_ALLUSERS, idata);
desktop = GetDesktopDir();
DeleteLinkList(startmenu,idata->startmenu,delstat);
DeleteLinkList(desktop,idata->desktop,delstat);
(DIR) diff --git a/win32/util.c b/win32/util.c
t@@ -323,6 +323,16 @@ void FreeInstData(InstData *idata,BOOL freepts) {
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[]="";
t@@ -412,19 +422,19 @@ static char *GetSpecialDir(int dirtype) {
return (doneOK ? bstrdup(szDir) : NULL);
}
-char *GetStartMenuTopDir(void) {
- return GetSpecialDir(CSIDL_STARTMENU);
+char *GetStartMenuTopDir(BOOL AllUsers) {
+ return GetSpecialDir(AllUsers ? CSIDL_COMMON_STARTMENU : CSIDL_STARTMENU);
}
char *GetDesktopDir(void) {
return GetSpecialDir(CSIDL_DESKTOPDIRECTORY);
}
-char *GetStartMenuDir(InstData *idata) {
+char *GetStartMenuDir(BOOL AllUsers, InstData *idata) {
bstr *str;
char *topdir,*retval;
- topdir=GetStartMenuTopDir();
+ topdir=GetStartMenuTopDir(AllUsers);
str = bstr_new();
t@@ -563,6 +573,18 @@ InstLink *ReadLinkList(HANDLE fin) {
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;
t@@ -645,12 +667,14 @@ InstData *ReadOldInstData(HANDLE fin,char *product,char *installdir) {
idata->instfiles = ReadFileList(fin);
idata->extrafiles = ReadFileList(fin);
+ idata->keepfiles = NULL;
idata->startmenu = ReadLinkList(fin);
idata->desktop = ReadLinkList(fin);
idata->service = ReadServiceDetails(fin);
- idata->keepfiles = ReadFileList(fin);
+
+ idata->flags = ReadInstFlags(fin);
return idata;
}
(DIR) diff --git a/win32/util.h b/win32/util.h
t@@ -46,6 +46,10 @@ typedef struct _NTService {
char *exe;
} NTService;
+typedef enum {
+ IF_ALLUSERS = 1
+} InstFlags;
+
typedef struct _InstData {
char *product;
char *installdir,*startmenudir;
t@@ -56,6 +60,7 @@ typedef struct _InstData {
InstFiles *keepfiles;
InstLink *startmenu;
InstLink *desktop;
+ InstFlags flags;
} InstData;
extern const char *UninstallKey;
t@@ -93,10 +98,11 @@ void AddServiceDetails(char *servicename,char *servicedisp,
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(void);
-char *GetStartMenuDir(InstData *idata);
+char *GetStartMenuTopDir(BOOL AllUsers);
+char *GetStartMenuDir(BOOL AllUsers, InstData *idata);
char *GetDesktopDir(void);
BOOL CreateWholeDirectory(char *path);
BOOL RemoveWholeDirectory(char *path);