source: trunk/gsinstaller/gsinstall.cpp@ 1475

Last change on this file since 1475 was 1475, checked in by cs025, 24 years ago

Updated sources with most of uninstall added

  • Property svn:keywords set to Author Date Id Revision
File size: 28.4 KB
Line 
1#include <vector>
2#include <string>
3using namespace std;
4
5#include <stdlib.h>
6#include <stdio.h>
7#include <windows.h>
8#include <commctrl.h>
9
10#include "dirSelector.h"
11#include "common.h"
12#include "configFile.h"
13#include "File.h"
14#include "FilePath.h"
15#include "FileCopier.h"
16#include "launchApp.h"
17#include "unInstall.h"
18
19#include "gsRegistry.h"
20#include "gsPlatform.h"
21#include "gsProgman.h"
22#include "gsProfile.h"
23#include "gsManifest.h"
24
25char * app_cmdLine;
26static char app_name[] = "Greenstone Installer";
27HINSTANCE app_instance;
28HWND app_window;
29
30bool config_complete = false;
31
32typedef vector<dirSelector *> dirSelVector;
33
34class GSInstall : public installManager
35{ private:
36 configureFile * configFile; // the installation configure file
37
38 FilePath * collectPath; // where the collection is currently installed
39 FilePath * installToPath; // the first cut at a destination folder
40 FilePath * sourcePath; // the root source folder
41 FilePath * gsdlSourcePath; // the gsdl folder in the source area
42 FilePath * destinationPath; // where the executables will be installed to
43 FilePath * dataDestPath; // where the collection data files will go
44
45 bool installVolume; // whether to install collection data
46 bool installFullVolume;// whether to install all collection data
47
48 dirSelVector selectedDirs; // configuration objects
49
50 gsPlatform platform; // platform information
51 gsRegistry * gsRegister; // registry
52 gsManifest * manifest; // manifest of files
53 gsProgramManager * progman; // program manager connection
54
55 void getSourcePath();
56 void getExistingInstall();
57 public:
58 bool installExe;
59
60 GSInstall(bool uninstall);
61 FilePath * collectionPath();
62 FilePath * installPath();
63 bool copyFiles();
64 bool updateRegistry();
65 bool updateProfiles();
66 bool updateProgman();
67 bool installNetscape();
68 void setDestination();
69 void setUninstall();
70 void uninstall();
71 void setManifest();
72 void addSelectedDir(dirSelector *selector);
73};
74
75static string gsdl_DBHOME = "gdbmhome";
76static string gsdl_VLHOME = "gsdlhome";
77static string gsdl_STATIC = "staticpath";
78static string gsdl_COLLIST= "collections";
79
80void gsInstall_getDesktopExt(int *sx, int *sy)
81{
82 HDC dc = GetDC(GetDesktopWindow());
83 *sx = GetDeviceCaps(dc, HORZRES);
84 *sy = GetDeviceCaps(dc, VERTRES);
85 ReleaseDC(GetDesktopWindow(), dc);
86}
87
88/**
89 * Get various and nefarious details before we start trying an installation.
90 * The installation configuration file is read, we seek for an existing
91 * installation and reconfigure the default install settings appropriately.
92 * THe source path is also discovered.
93 */
94GSInstall::GSInstall(bool uninstall)
95 : installManager()
96{ // get the installation configuration file
97 this->configFile = new configureFile("install.cfg");
98
99 // set up "default" installation bits
100 this->installToPath = new FilePath("C:\\GSDL");
101 this->collectPath = NULL;
102 this->installExe = true; // we must install the exe files
103
104 // don't attempt this with windows 3.1
105 if (!this->platform.isWindows32s())
106 { // get the registry
107 this->gsRegister = new gsRegistry(*this, *this->configFile);
108 }
109 else
110 { // TODO: in windows 3.1 we can't use the register as it isn't fully/properly
111 // implemented; we must get the existing path information from elsewhere
112 this->gsRegister = new gsRegistry(*this, *this->configFile);
113 }
114
115 // assume for now we will install the full volume and the database
116 this->installVolume = true;
117 this->installFullVolume = true;
118
119 // detect any existing installation; unnecessary in uninstall (it's the
120 // "source" directory - see later
121 if (uninstall == false)
122 { this->getExistingInstall();
123 }
124
125 // get where we are installing from
126 this->getSourcePath();
127
128 // if doing an uninstall we now know where the "uninstall" is
129 if (uninstall == true)
130 { this->collectPath = this->sourcePath;
131 }
132
133 // get the manifest and program manager objects
134 if (uninstall)
135 { this->manifest = new gsManifest(*this);
136 }
137 else
138 { this->manifest = new gsManifest(*this, *this->sourcePath);
139 }
140 this->progman = new gsProgramManager(*this);
141
142 // tell manifest the number of bits in the raw windows environment; this may
143 // be required for loading certain modules such as winsock; the number of
144 // macros is over-the-top, but is more robust to unforeseen future requirements
145/* if (platform.isWindows32s())
146 { this->manifest->expandMacro("WINBITS", "16");
147 this->manifest->expandMacro("WIN16", "16");
148 this->manifest->expandMacro("WIN32", "32");
149 }
150 else
151 { this->manifest->expandMacro("WINBITS", "32");
152 this->manifest->expandMacro("WIN16", "");
153 this->manifest->expandMacro("WIN32", "32");
154 }
155*/
156 // inform manifest of collection directory name
157 string colDir;
158 colDir = this->configFile->getString("CollectionDirName");
159 if (colDir != "")
160 { this->manifest->expandMacro("COLDIRNAME", colDir);
161 }
162}
163
164/**
165 * Detect the presence of an existing installation
166 */
167void GSInstall::getExistingInstall()
168{ if (!this->platform.isWindows32s())
169 { if (gsRegister->collectionInstalled())
170 { // TODO: check if receptionist etc should be replaced or not
171
172 // TODO: check build version of the volume
173
174 // Get location of the library executable from the registry; this
175 // is thence used to get the location of gsdl.ini etc.
176 this->collectPath = this->gsRegister->collectionPath();
177 if (this->collectPath != "")
178 { this->installToPath = this->collectPath;
179
180 // we don't need to install the exe files
181 this->installExe = false;
182 }
183 }
184 }
185}
186
187/**
188 * get the source path for this install; we derive this from the path of this
189 * executable (the installer)
190 */
191void GSInstall::getSourcePath()
192{ static char filename[512];
193 FilePath *exePath;
194
195 // get the filepath of this executable
196 GetModuleFileName(0, filename, 512);
197 exePath = new FilePath(filename);
198
199 // get the parent (i.e. the folder containing this executable) for the source
200 // folder
201 this->sourcePath = exePath->parent();
202
203 // get the gsdl source path
204 this->gsdlSourcePath = new FilePath(this->sourcePath->pathString(), "gsdl");
205 delete exePath;
206}
207
208/**
209 * Controls the actual copying of the files; manifests of what to install
210 * are read in from a configuration on the hard drive - this should be basically
211 * greenstone dependent, and void of any collection-specific rubbish!
212 */
213bool GSInstall::copyFiles()
214{ // ensure that we have got the required destination and that we can write there
215 if (this->installExe)
216 { this->destinationPath->ensureWriteablePath();
217 }
218
219 // ensure that the destination path for the collection itself is available
220 if (this->installVolume)
221 { this->dataDestPath->ensureWriteablePath();
222 }
223
224 // do the copy
225 this->manifest->copy(this->gsdlSourcePath);
226
227 return true;
228}
229
230/**
231 * Fulfill registry update requirements; first the keys are set up, then they
232 * are filled with key item/value pairs.
233 */
234bool GSInstall::updateRegistry()
235{ // don't do registry stuff under windows 32s
236 if (this->platform.isWindows32s() && FALSE)
237 { return true;
238 }
239
240 // ensure all pertinent keys already exist for this volume/collection
241 this->gsRegister->ensureKeysExist();
242
243 // now move on to add key items
244 if (this->installExe)
245 { FilePath *serverPath = new FilePath(this->destinationPath->pathString(), "server.exe");
246 FilePath *setupPath = new FilePath(this->destinationPath->pathString(), "gssetup.exe");
247 FilePath *logPath = new FilePath(this->destinationPath->pathString(), "install.log");
248 string exeKeyPath, uninstallCmd, uninstallKeyPath;
249 gsPlatform platform;
250
251 // store the normal collection key information
252 this->gsRegister->storeKeyString( HKEY_LOCAL_MACHINE,
253 this->gsRegister->collectKeyId(),
254 "library",
255 serverPath->pathString());
256
257 // This test is in fact for 9x or NT 4+; we're worried about the registry
258 // format, not about the shell as such
259 if (platform.isExplorerShell())
260 { // get special app path key for windows 9x
261 exeKeyPath = this->gsRegister->exeKeyId("library.exe");
262
263 // ensure that the exe key exists
264 this->gsRegister->ensureKeyExists(HKEY_LOCAL_MACHINE, exeKeyPath);
265
266 // store default key for this application
267 this->gsRegister->storeKeyString( HKEY_LOCAL_MACHINE,
268 exeKeyPath,
269 "",
270 serverPath->pathString());
271
272 // store path for this application
273 this->gsRegister->storeKeyString( HKEY_LOCAL_MACHINE,
274 exeKeyPath,
275 "path",
276 this->destinationPath->pathString());
277
278 // create uninstall command line
279 uninstallCmd = setupPath->pathString() + " -u " + logPath->pathString();
280 uninstallKeyPath = this->gsRegister->uninstallKeyId(this->configFile->getString("CollectionName"));
281
282 // ensure uninstall key exists
283 this->gsRegister->ensureKeyExists(HKEY_LOCAL_MACHINE, uninstallKeyPath);
284
285 this->gsRegister->storeKeyString(HKEY_LOCAL_MACHINE, uninstallKeyPath,
286 "DisplayName",
287 this->configFile->getString("CollectionName"));
288 this->gsRegister->storeKeyString(HKEY_LOCAL_MACHINE, uninstallKeyPath,
289 "UninstallString", uninstallCmd);
290 }
291 delete setupPath;
292 delete serverPath;
293 delete logPath;
294 }
295
296 if (this->installVolume || this->installFullVolume)
297 { // no actual key items are held in the volume key; for future use
298 }
299 return true;
300}
301
302/**
303 * Set the destination directory details
304 */
305void GSInstall::setDestination()
306{ // get configuration from the install wizard pages
307 this->destinationPath = new FilePath(this->selectedDirs[0]->selectedPath());
308 this->installFullVolume = this->selectedDirs[1]->getOption();
309 if (this->installFullVolume || true) // NB: always take path from 2nd dialog
310 { this->dataDestPath = new FilePath(this->selectedDirs[1]->selectedPath());
311 }
312 else
313 { this->dataDestPath = this->destinationPath;
314 }
315
316 // open the log for writing
317 FilePath *logPath = new FilePath(this->destinationPath->pathString(), "install.log");
318 this->openLog(logPath->pathString(), true);
319 delete logPath;
320}
321
322void GSInstall::setUninstall()
323{
324 // open the log for reading
325 FilePath *logPath = new FilePath(this->collectPath->pathString(), "install.log");
326 this->openLog(logPath->pathString(), false);
327 delete logPath;
328}
329
330void GSInstall::uninstall()
331{ FilePath *iniPath;
332 string command;
333 stringArray params;
334
335 this->manifest = new gsManifest(*this); // get a manifest manager
336
337 iniPath = new FilePath(this->collectPath->pathString(), "gsdl.ini");
338 gsProfile gsdlProfile(*this, iniPath->pathString());
339
340 while ((command = this->readCommand(params)) != "")
341 { if (!this->manifest->undoAction(command, params))
342 { if (!gsdlProfile.undoAction(command, params))
343 { if (!this->gsRegister->undoAction(command, params))
344 { if (!this->progman->undoAction(command, params))
345 {
346 }
347 }
348 }
349 }
350 }
351}
352
353/**
354 * Collate the manifest for installation
355 */
356void GSInstall::setManifest()
357{ if (this->installExe)
358 { this->manifest->selectGroup("library", *this->destinationPath);
359 }
360 if (this->installFullVolume)
361 { this->manifest->selectGroup("collection", *this->dataDestPath);
362 }
363 else
364 { this->manifest->selectGroup("database", *this->dataDestPath);
365 }
366}
367
368/**
369 * Update the program manager/explorer shell with icons, groups etc for this
370 * collection/application
371 */
372bool GSInstall::updateProgman()
373{ string groupName;
374
375 // if we managed to get a connection to the program manager (or explorer
376 // shell) then do the requisite updates
377 if (this->progman->connect())
378 { // get group name from folders
379 groupName = this->configFile->getString("ProgramGroupName");
380 if (groupName == "")
381 { // TODO: error handling
382 this->progman->disconnect();
383 return false;
384 }
385
386 // add the group
387 if (!this->progman->addProgramGroup(groupName))
388 { this->progman->disconnect();
389 return false;
390 }
391
392 // add a "server" icon
393 FilePath libraryPath(this->destinationPath->pathString(), "library.exe");
394 if (!this->progman->addIcon(groupName, "Library (without nextwork support)", libraryPath.pathString(), ""))
395 { // assume that it may be there already
396 }
397
398 // check for server existence
399 FilePath serverPath(this->destinationPath->pathString(), "server.exe");
400 if (serverPath.exists())
401 { if (!this->progman->addIcon(groupName, "Server", serverPath.pathString(), ""))
402 { // assume that it may be there already
403 }
404 }
405
406 FilePath readMePath(this->destinationPath->pathString(), "readme.txt");
407 if (!this->progman->addIcon(groupName, "ReadMe", readMePath.pathString(), ""))
408 {
409 }
410
411 FilePath supportPath(this->destinationPath->pathString(), "support.html");
412 if (!this->progman->addIcon(groupName, "Technical Support", supportPath.pathString(), ""))
413 {
414 }
415
416 // TODO: uninstall icon
417 // FilePath uninstallPath(this->destinationPath->pathString(), "gssetup.exe");
418
419 // disconnect from program manager
420 this->progman->disconnect();
421 }
422 return true;
423}
424
425/**
426 * Update the profile (ini) files associated with the program; these changes
427 * must be made after copying to files in the destination/executable folders
428 * as we can't write to CD-ROM (or at least we shouldn't - the install would
429 * become tainted).
430 */
431bool GSInstall::updateProfiles()
432{ FilePath *exePath;
433 FilePath *dataPath;
434 FilePath *iniPath;
435
436 // if we're installing the exe, then the exe path leads to the destination
437 // folder of this installation sequence; if not, then we pick it up from
438 // the existing location of that folder
439 if (this->installExe)
440 { exePath = this->destinationPath;
441 }
442 else
443 { exePath = this->collectPath;
444 }
445 iniPath = new FilePath(exePath->pathString(), "gsdl.ini");
446
447 // TODO: check if this 'if' structure is correct; suspect that it isn't quite
448 // as we may not be installing the volume, but exe etc individually;
449 // may be okay now but not future proof; also the destination directory
450 // may or may not be tied to the exe directory if that existed already.
451 // This all needs investigating
452 if (this->installVolume)
453 { // Manufacture the appropriate section name now; an equivalent string
454 // is also constructed
455 string volumeSectionString = this->configFile->getString("CollectionName") +
456 "#" + this->configFile->getString("CollectionVolume");
457
458 // if we're installing the full data for the collection, then take the
459 // data path to be at the selected destination directory for the collection
460 // files; otherwise take the data path to be on the CD/distribution media
461 if (this->installFullVolume)
462 { dataPath = this->dataDestPath;
463 }
464 else
465 { dataPath = this->gsdlSourcePath;
466 }
467
468 // create a profile object to write to the gsdl.ini file
469 gsProfile gsdlProfile(*this, iniPath->pathString());
470
471 // if installing the executable, add the database and greenstone home
472 // directories
473 if (this->installExe)
474 { // set the correct exe entries in gsdl.ini (in the gsdl section)
475 gsdlProfile.writeString("gsdl", "gsdlhome", dataPath->pathString());
476 gsdlProfile.writeString("gsdl", "gdbmhome", this->dataDestPath->pathString());
477 }
478
479 // set the correct collection volume entries in gsdl.ini
480 if (this->installVolume)
481 { // note the collection in the general gsdl section; and add the undo item too
482 gsdlProfile.ensureListMember("gsdl", gsdl_COLLIST, volumeSectionString);
483
484 // note the volume data in its own section
485 gsdlProfile.writeString(volumeSectionString, "gsdlhome", dataPath->pathString());
486 gsdlProfile.writeString(volumeSectionString, "gdbmhome", this->dataDestPath->pathString());
487 gsdlProfile.writeString(volumeSectionString, "staticpath", dataPath->pathString());
488 }
489 }
490
491 // clean up
492 delete iniPath;
493
494 return true;
495}
496
497bool GSInstall::installNetscape()
498{ FilePath netscape32Path(this->sourcePath->pathString(), "netscape\\n32e405.exe");
499 FilePath netscape16Path(this->sourcePath->pathString(), "netscape\\n16e405.exe");
500
501 launchApp launchNetscape(netscape32Path);
502 launchNetscape.platformApp(gsPlatform_WINDOWS32S, netscape16Path);
503 if (launchNetscape.run(true, 1,
504 "This library is displayed using a web browser. If you don't "
505 "currently have a web browser installed on your machine you may "
506 "install the Netscape 4.05 browser now.\n\n"
507 "Note that if your current browser was provided by your internet "
508 "service provider, you should install Netscape in a different "
509 "directory.\n\n"
510 "Would you like to install the Netscape 4.05 browser now?",
511 "Greenstone Installer", false) < 0)
512 { MessageBox(0, "Error", app_name, MB_OK);
513 return false;
514 }
515 return true;
516}
517
518FilePath *GSInstall::collectionPath()
519{ return this->collectPath;
520}
521
522FilePath *GSInstall::installPath()
523{ return this->installToPath;
524}
525
526void GSInstall::addSelectedDir(dirSelector *selector)
527{ this->selectedDirs.push_back(selector);
528}
529
530typedef struct
531{ dirSelector * dirSelect;
532} GSInstall_dirPathData;
533
534HGLOBAL loadDirBrowser()
535{ HRSRC resHdl;
536
537 resHdl = FindResource(app_instance, "MySaveAsDlg", RT_DIALOG);
538 return LoadResource(app_instance, resHdl);
539}
540
541void gsInstall_wizard_centre(HWND dialog)
542{
543 RECT rect;
544 int sx, sy;
545 int dx, dy;
546
547 gsInstall_getDesktopExt(&sx, &sy);
548 GetWindowRect(dialog, &rect);
549
550 dx = (sx - rect.right + rect.left) >> 1;
551 dy = (sy - rect.bottom + rect.top) >> 1;
552 SetWindowPos(dialog, 0, dx, dy, 0, 0, SWP_NOZORDER | SWP_NOSIZE);
553}
554
555BOOL FAR PASCAL GSInstall_dlgproc(HWND Dialog, UINT Message, WPARAM wParam, LPARAM lParam)
556{ static bool first = true; // static variable to hack the position of the
557 // whole wizard; note doing this in the wizard
558 // property sheet initialisation DOES NOT WORK
559
560 switch (Message)
561 { case WM_INITDIALOG:
562 { dirSelector *selector = (dirSelector *) ((PROPSHEETPAGE *) lParam)->lParam;
563
564 SetDlgItemText(Dialog, dirpath_PROMPT, selector->prompt);
565 if (selector->optPrompt != NULL)
566 { SetDlgItemText(Dialog, dirpath_OPTION, selector->optPrompt);
567 EnableWindow(GetDlgItem(Dialog, dirpath_BROWSE), true); // was false
568 EnableWindow(GetDlgItem(Dialog, dirpath_PATH), true); // was false
569 }
570 else
571 { ShowWindow(GetDlgItem(Dialog, dirpath_OPTION), SW_HIDE);
572 }
573 SetWindowLong(Dialog, GWL_USERDATA, ((PROPSHEETPAGE *) lParam)->lParam);
574 SetDlgItemText(Dialog, dirpath_PATH, selector->selectedPath());
575
576 // if this is the first time this function is called, then centre the
577 // wizard into the centre of our screen.
578 if (first)
579 { gsInstall_wizard_centre(GetParent(Dialog));
580 first = false;
581 }
582 }
583 return TRUE;
584
585 case WM_COMMAND:
586 switch (LOWORD(wParam))
587 { case dirpath_BROWSE:
588 ((dirSelector *) GetWindowLong(Dialog, GWL_USERDATA))->requestPath(Dialog, "Select Directory");
589 SetDlgItemText(Dialog, dirpath_PATH, ((dirSelector *) GetWindowLong(Dialog, GWL_USERDATA))->selectedPath());
590 break;
591
592 case dirpath_OPTION:
593 ((dirSelector *) GetWindowLong(Dialog, GWL_USERDATA))->setOption(IsDlgButtonChecked(Dialog, dirpath_OPTION));
594 if (HIWORD(wParam) == BN_CLICKED && false) // don't do the enable/disable these days
595 { EnableWindow(GetDlgItem(Dialog, dirpath_BROWSE), IsDlgButtonChecked(Dialog, dirpath_OPTION));
596 EnableWindow(GetDlgItem(Dialog, dirpath_PATH), IsDlgButtonChecked(Dialog, dirpath_OPTION));
597 }
598 break;
599 }
600 break;
601
602 case WM_NOTIFY:
603 switch (((LPNMHDR) lParam)->code)
604 { case PSN_SETACTIVE:
605 { dirSelector *selector = ((dirSelector *) GetWindowLong(Dialog, GWL_USERDATA));
606 if (selector->isFinal())
607 { PropSheet_SetWizButtons(GetParent(Dialog), PSWIZB_BACK | PSWIZB_FINISH);
608 }
609 else
610 { PropSheet_SetWizButtons(GetParent(Dialog), PSWIZB_BACK | PSWIZB_NEXT);
611 }
612 }
613 break;
614
615 case PSN_KILLACTIVE:
616 break;
617
618 case PSN_WIZNEXT:
619 { // note the path from the dialog
620 dirSelector *selector = ((dirSelector *) GetWindowLong(Dialog, GWL_USERDATA));
621 selector->setPathFromEdit(GetDlgItem(Dialog, dirpath_PATH));
622
623 // create a new FilePath object to check on the proposed destination
624 FilePath *path = new FilePath(selector->selectedPath());
625
626 // if the proposed destination doesn't exist, ask the user whether to
627 // create it now. TODO: actually create it if asked!
628 if (path->exists() == false)
629 { char buffer[128];
630
631 sprintf(buffer, "Directory %s does not exist - create it?", selector->selectedPath());
632
633 // if the user cancelled that, then don't permit them to go to the next
634 // page of the wizard
635 if (MessageBox(0, buffer, app_name, MB_YESNO | MB_TOPMOST) == IDNO)
636 { delete path;
637 SetWindowLong(Dialog, DWL_MSGRESULT, TRUE);
638 return TRUE;
639 }
640 }
641 delete path;
642 }
643 break;
644
645 case PSN_WIZFINISH:
646 { // Finish the activity now
647 config_complete = true;
648 }
649 break;
650 }
651 break;
652 }
653 return FALSE;
654}
655
656void GSInstall_init_propertySheet(PROPSHEETPAGE &ppage, char *prompt, char *optPrompt,
657 char *title, GSInstall &installer, bool isFinal)
658{ GSInstall_dirPathData *data = new GSInstall_dirPathData;
659
660 data->dirSelect = new dirSelector(prompt, optPrompt, title, installer.installPath());
661 data->dirSelect->setFinal(isFinal);
662
663 installer.addSelectedDir(data->dirSelect);
664
665 ppage.dwSize = sizeof(PROPSHEETPAGE);
666 ppage.dwFlags = PSP_USETITLE;
667 ppage.hInstance = app_instance;
668 ppage.pszTemplate = "getDirPath";
669 ppage.pszIcon = 0;
670 ppage.pszTitle = app_name;
671 ppage.pfnDlgProc = (DLGPROC) GSInstall_dlgproc;
672 ppage.lParam = (LPARAM) data->dirSelect;
673 ppage.pfnCallback = NULL;
674}
675
676int CALLBACK GSInstall_wizardProc(HWND dialog, UINT Message, LPARAM lParameter)
677{ switch (Message)
678 { case PSCB_INITIALIZED :
679 // Process PSCB_INITIALIZED
680 gsInstall_wizard_centre(dialog);
681 break ;
682
683 case PSCB_PRECREATE :
684 // Process PSCB_PRECREATE
685 break ;
686
687 default :
688 // Unknown message
689 break ;
690 }
691 return 0;
692}
693
694bool GSInstall_init_wizard(GSInstall &install)
695{ PROPSHEETHEADER pshead;
696 PROPSHEETPAGE ppage[2];
697 bool reply;
698
699 ZeroMemory(&pshead, sizeof(PROPSHEETHEADER));
700 pshead.dwSize = sizeof(PROPSHEETHEADER);
701 pshead.dwFlags = PSH_PROPSHEETPAGE | PSH_USECALLBACK | PSH_USEHICON | PSH_WIZARD;
702 pshead.hwndParent = app_window;
703 pshead.hInstance = app_instance;
704 pshead.hIcon = NULL;
705 pshead.pszCaption = "Greenstone Installer";
706 pshead.nPages = 2;
707 pshead.nStartPage = 0;
708 if (install.installExe == true)
709 { pshead.ppsp = ppage;
710 }
711 else // cheat as the executable etc. is already installed
712 { pshead.ppsp = &ppage[1];
713 }
714 pshead.pfnCallback = GSInstall_wizardProc;
715
716 GSInstall_init_propertySheet( ppage[0],
717 "Choose a directory to install your "
718 "GreenStone software to.", NULL,
719 "Select", install, false);
720 GSInstall_init_propertySheet(ppage[1],
721 "Choose a directory to install the collection "
722 "files to.\n\n"
723 "You can also choose to install all the collection "
724 "files onto your computer hard drive.\n\n"
725 "If you do this, you will not have to load the "
726 "CD-ROM each time you use your Greenstone software "
727 "but more of your hard disk will be used.\n\n"
728 "Some collection files must be installed on your "
729 "computer.\n\n",
730 "Install all collection files",
731 "Select", install, true);
732
733 reply = (PropertySheet (&pshead) >= 0);
734 return reply;
735}
736
737long FAR PASCAL GSInstallWindProc(HWND Window,
738 WORD Message,
739 WPARAM wParameter,
740 LPARAM lParameter)
741{ long reply = 0;
742
743 switch(Message)
744 { case WM_CREATE:
745 { ShowWindow(Window, SW_MAXIMIZE);
746 }
747 break;
748
749 case WM_COMMAND:
750 break;
751
752 case WM_USER:
753 { // uninstall action
754 if (strstr(app_cmdLine, "-u") != NULL || true)
755 { char *at = strstr(app_cmdLine, "-u");
756 at += strlen("-u") + 1;
757
758 GSInstall install(true);
759 install.setUninstall();
760 install.uninstall();
761 }
762 // install wizard
763 else
764 { GSInstall install(false);
765 GSInstall_init_wizard(install);
766 if (config_complete == false)
767 { MessageBox(0, "Install cancelled", app_name, MB_OK);
768 }
769 else
770 { // configure the installation
771 install.setDestination();
772 install.setManifest();
773
774 // perform installation
775 install.copyFiles();
776 install.updateProgman();
777 install.updateRegistry();
778 install.updateProfiles();
779
780 // do further actions
781 install.installNetscape();
782 }
783 }
784 DestroyWindow(Window);
785 }
786 break;
787
788 case WM_CLOSE:
789/* if (!file_ischanged || IDCANCEL != file_query(Window, file_name))*/
790 DestroyWindow(Window);
791 return 0L;
792
793 case WM_DESTROY:
794 { PostQuitMessage(0);
795 }
796 break;
797
798 default:
799 return(DefWindowProc(Window, Message, wParameter, lParameter));
800 }
801 return reply;
802}
803
804void GSInstall_init(HINSTANCE instance, int Show)
805{ int sx, sy;
806
807 gsInstall_getDesktopExt(&sx, &sy);
808
809 app_window = CreateWindow("GSInstall:Main", "GreenStone Installer",
810 WS_OVERLAPPEDWINDOW | WS_MAXIMIZE | CS_DBLCLKS,
811 0, 0,
812 sx, sy,
813 NULL,
814 NULL,
815 app_instance,
816 NULL);
817
818 ShowWindow(app_window, Show);
819
820 PostMessage(app_window, WM_USER, 0, 0L);
821}
822
823void WinClassInit(void)
824{ WNDCLASS Class;
825
826 Class.lpszClassName = "GSInstall:Main";
827 Class.hInstance = app_instance;
828 Class.lpfnWndProc = (WNDPROC) GSInstallWindProc;
829 Class.hCursor = LoadCursor(NULL, IDC_ARROW);
830 Class.hIcon = NULL; //LoadIcon(app_instance, "GSInstall");
831 Class.lpszMenuName = NULL;
832 Class.hbrBackground = (HBRUSH) (COLOR_APPWORKSPACE+1);
833 Class.style = NULL;
834 Class.cbClsExtra = 0;
835 Class.cbWndExtra = 0;
836 RegisterClass(&Class);
837/*
838 Class.lpszClassName = "GSInstall:Splash";
839 Class.hInstance = app_instance;
840 Class.lpfnWndProc = (WNDPROC) splash_windproc;
841 Class.hCursor = LoadCursor(NULL, IDC_ARROW);
842 Class.hIcon = NULL;
843 Class.lpszMenuName = NULL;
844 Class.hbrBackground = (HBRUSH) (COLOR_WINDOW+1);
845 Class.style = NULL;
846 Class.cbClsExtra = 0;
847 Class.cbWndExtra = 0;
848 RegisterClass(&Class);*/
849}
850
851int PASCAL WinMain(HINSTANCE Current,
852 HINSTANCE Previous,
853 LPSTR CmdLine,
854 int CmdShow)
855{ MSG msg;
856// HACCEL accel;
857
858 app_cmdLine = (char *) malloc(lstrlen(CmdLine) + 1);
859 lstrcpy(app_cmdLine, CmdLine);
860
861 app_instance = Current;
862 /* -- init application */
863 if (!Previous)
864 { WinClassInit();
865 InitCommonControls();
866// grbStatic_registerClass(Current);
867 }
868
869 /* -- init instance */
870 GSInstall_init(Current, CmdShow);
871
872// config_init("ReTreeval");
873
874// accel = LoadAccelerators(Current, "ReTreevalMenu");
875
876 while (GetMessage(&msg, NULL, 0, 0))
877 { /*if (!TranslateAccelerator(app_window, accel, &msg))
878 { */
879 TranslateMessage(&msg);
880 DispatchMessage(&msg);
881 /*}*/
882 }
883 return (int) msg.wParam;
884}
Note: See TracBrowser for help on using the repository browser.