source: trunk/gsdl/src/w32server/fnord.cpp@ 2354

Last change on this file since 2354 was 2354, checked in by sjboddie, 23 years ago

* empty log message *

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 33.1 KB
Line 
1/**********************************************************************
2 *
3 * fnord.cpp
4 * Copyright (C) 1996
5 *
6 * A component of the fnord webserver written by [email protected].
7 *
8 * Altered for use with the Greenstone digital library software by the
9 * New Zealand Digital Library Project at the University of Waikato,
10 * New Zealand.
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *
26 *********************************************************************/
27
28#include "text_t.h"
29#include <windows.h>
30#include <stdlib.h>
31#include <stdio.h>
32#include <string.h>
33#include <memory.h>
34#pragma hdrstop
35#include "netio.h"
36#include "settings.h"
37#include "httpsrv.h"
38#include "resource.h"
39#include "locate.h"
40#include "cgiwrapper.h"
41#include "startbrowser.h"
42#include "d_winsock.h"
43
44#define MAINWINDOWWIDTH 400
45#define MAINWINDOWHEIGHT 200
46
47#define WASTEHEIGHT 44 // Error in ht due to caption and menu bar
48#define WASTEWIDTH 6
49#define SPACERWIDTH 5
50
51// size and position of the collection title
52#define COLTITLEWIDTH 351
53#define COLTITLEHEIGHT 35
54#define COLTITLEX ((MAINWINDOWWIDTH-COLTITLEWIDTH)/2)
55#define COLTITLEY 10
56
57// size and position of the version string
58#define VERSIONWIDTH MAINWINDOWWIDTH
59#define VERSIONHEIGHT 20
60#define VERSIONX 0
61#define VERSIONY (COLTITLEY+COLTITLEHEIGHT)
62
63// size and position of the Greenstone digital library logo
64#define LOGOWIDTH 135
65#define LOGOHEIGHT 55
66#define LOGOX (MAINWINDOWWIDTH-(LOGOWIDTH+SPACERWIDTH))
67#define LOGOY (MAINWINDOWHEIGHT-(LOGOHEIGHT+SPACERWIDTH))
68
69// size and position of the enter button
70#define ENTERBUTTONWIDTH 160
71#define ENTERBUTTONHEIGHT 30
72#define ENTERBUTTONX SPACERWIDTH
73#define ENTERBUTTONY ((MAINWINDOWHEIGHT-(LOGOHEIGHT+SPACERWIDTH))-(ENTERBUTTONHEIGHT+SPACERWIDTH))
74
75// size and position of the enter string
76#define ENTERSTRINGX (ENTERBUTTONX+ENTERBUTTONWIDTH+SPACERWIDTH)
77#define ENTERSTRINGY ENTERBUTTONY
78#define ENTERSTRINGWIDTH (MAINWINDOWWIDTH-(ENTERBUTTONWIDTH+SPACERWIDTH+SPACERWIDTH+SPACERWIDTH))
79#define ENTERSTRINGHEIGHT ENTERBUTTONHEIGHT
80
81// size and position of the info string
82#define INFOWIDTH MAINWINDOWWIDTH
83#define INFOHEIGHT (MAINWINDOWHEIGHT-INFOY)
84#define INFOX 0
85#define INFOY ENTERBUTTONY
86
87// size and position of restricted buttons
88#define ALTERNATIVEBUTTONWIDTH 160
89#define ALTERNATIVEBUTTONHEIGHT 30
90#define ALTERNATIVEBUTTONX SPACERWIDTH
91#define ALTERNATIVEBUTTONY LOGOY
92
93#define INFOBUTTONWIDTH 30
94
95// size and position of restart button
96#define RESTARTBUTTONWIDTH 160
97#define RESTARTBUTTONHEIGHT 30
98#define RESTARTBUTTONX 50
99#define RESTARTBUTTONY (MAINWINDOWHEIGHT-RESTARTBUTTONHEIGHT-15)
100
101
102#define VERSIONSTRING "version x.xx"
103const char versionstring[] = VERSIONSTRING;
104
105const char strnothing[] = "";
106const char strinit[] = "Initialising...";
107const char strsb[] = "Starting browser...";
108const char strrestartlib[] = "Press the 'Restart Library' button to start a browser\n"
109"and enter library";
110const char strenterlib[] = "Press this button to begin using\n"
111"the library";
112const char *enterstring = NULL; // points to the current enter string
113const char *infostring = NULL; // points to the current info string
114
115
116// globals to do with networking and browsers
117int have_networking = 0;
118int netscapeneeded = 0;
119char startbrowserdir[1024] = ""; // HARD LIMIT!!!!!
120
121
122// stats to do with the last time the enter library button was pressed
123// these stats are needed to make suggestions about the proxy
124int enterlib_libaccessnum = -1; // -1 = NA
125DWORD enterlib_time = 0;
126
127
128enum { undefined_window, console_window, plain_window }
129window_state;
130
131HDC coltitledc = NULL;
132HBITMAP defcoltitlebitmap = NULL, coltitlebitmap=NULL;
133
134HDC logodc=NULL;
135HBITMAP deflogobitmap=NULL, logobitmap=NULL;
136
137HWND GoButton = NULL;
138HWND Enter = NULL;
139HWND EnterRestricted = NULL;
140HWND InfoRestricted = NULL;
141int init_type = 0;
142int init_done = 0;
143
144void finish_up() {
145 // remember the current preferences
146 write_settings();
147
148 // Shutdown the HTTP server
149 EndHTTPServer();
150
151 // Shutdown the main server modules
152 CleanUpNetIO();
153 // RemoveFnordFromTray();
154
155 // Unload the wsock32 dll
156 d_UnloadWinsock();
157
158 // Clean up graphics stuff from window
159
160 if (defcoltitlebitmap != NULL)
161 SelectObject (coltitledc, defcoltitlebitmap);
162 if (coltitlebitmap != NULL)
163 DeleteObject (coltitlebitmap);
164 if (coltitledc != NULL)
165 DeleteDC (coltitledc);
166
167 if (deflogobitmap != NULL)
168 SelectObject (logodc, deflogobitmap);
169 if (logobitmap != NULL)
170 DeleteObject (logobitmap);
171 if (logodc != NULL)
172 DeleteDC (logodc);
173
174 // Shutdown the main window
175 PostQuitMessage(0);
176}
177
178
179int overlap(int left, int top, int right, int bottom,
180 RECT &r2)
181{
182 if (left <= r2.right && r2.left <= right &&
183 top <= r2.bottom && r2.top <= bottom)
184 return 1;
185 else
186 return 0;
187}
188
189
190void paint_window (HDC pdc, RECT &updateRect) {
191 // make sure the various DCs are set up
192 if (coltitledc == NULL) {
193 coltitledc = CreateCompatibleDC(pdc);
194 defcoltitlebitmap = (HBITMAP)SelectObject (coltitledc, coltitlebitmap);
195 }
196
197 if (logodc == NULL) {
198 logodc = CreateCompatibleDC(pdc);
199 deflogobitmap = (HBITMAP)SelectObject (logodc, logobitmap);
200 }
201
202 // remove any remaining sign of initial buttons
203 if (init_done && (overlap (ENTERBUTTONX, ENTERBUTTONY, ENTERBUTTONX+ENTERBUTTONWIDTH,
204 ALTERNATIVEBUTTONY+ALTERNATIVEBUTTONHEIGHT, updateRect))) {
205 RECT initRect;
206 initRect.left = ENTERBUTTONX;
207 initRect.top = ENTERBUTTONY;
208 initRect.right = ENTERBUTTONX+ENTERBUTTONWIDTH;
209 initRect.bottom = ALTERNATIVEBUTTONY+ALTERNATIVEBUTTONHEIGHT;
210 FillRect(pdc, &initRect, (HBRUSH)GetStockObject(WHITE_BRUSH));
211 }
212
213 // update the collection title if needed
214 if (overlap(COLTITLEX, COLTITLEY,
215 COLTITLEX+COLTITLEWIDTH, COLTITLEY+COLTITLEHEIGHT,
216 updateRect)) {
217 BitBlt (pdc, COLTITLEX, COLTITLEY,
218 COLTITLEX+COLTITLEWIDTH, COLTITLEY+COLTITLEHEIGHT,
219 coltitledc, 0, 0, SRCCOPY);
220 }
221
222 // update the version string if needed
223 if (overlap (VERSIONX, VERSIONY,
224 VERSIONX+VERSIONWIDTH, VERSIONY+VERSIONHEIGHT,
225 updateRect)) {
226 RECT versionRect;
227 versionRect.left = VERSIONX;
228 versionRect.top = VERSIONY;
229 versionRect.right = VERSIONX+VERSIONWIDTH;
230 versionRect.bottom = VERSIONY+VERSIONHEIGHT;
231 DrawText(pdc, versionstring, -1, &versionRect, DT_CENTER);
232 }
233
234 // decide what we want to draw
235 if (init_done && gsdl_show_console) {
236 // we want to draw a "console" window
237 if (window_state != console_window ||
238 overlap (text_rect.left, text_rect.top,
239 text_rect.right, text_rect.bottom,
240 updateRect)) {
241 refresh_console (pdc);
242 }
243
244 window_state = console_window;
245
246 } else {
247 // we want to draw a "plain" window
248
249 // update the enter string if needed
250 if (overlap (ENTERSTRINGX, ENTERSTRINGY, ENTERSTRINGX+ENTERSTRINGWIDTH,
251 ENTERSTRINGY+ENTERSTRINGHEIGHT, updateRect)) {
252
253 RECT enterstringRect;
254 enterstringRect.left = ENTERSTRINGX;
255 enterstringRect.top = ENTERSTRINGY;
256 enterstringRect.right = ENTERSTRINGX+ENTERSTRINGWIDTH;
257 enterstringRect.bottom = ENTERSTRINGY+ENTERSTRINGHEIGHT;
258 FillRect(pdc, &enterstringRect, (HBRUSH)GetStockObject(WHITE_BRUSH));
259
260 if ((enterstring != NULL) && (strlen(enterstring) > 0)) {
261
262 int cury = ENTERSTRINGY;
263 int startline = 0, here = 0;
264 while (enterstring[here] != '\0') {
265 if (enterstring[here] < ' ') {
266 if (here - startline > 0) {
267 // output the text
268 TextOut (pdc, ENTERSTRINGX, cury,
269 &enterstring[startline], here-startline);
270 cury += line_spacing;
271 }
272 startline = here+1;
273 }
274 here++;
275 }
276 // output any remaining text
277 if (here - startline > 0) {
278 TextOut (pdc, ENTERSTRINGX, cury, &enterstring[startline], here-startline);
279 }
280 }
281 }
282
283 window_state = plain_window;
284 }
285
286 // update the info string if needed
287 if (init_done && !gsdl_show_console &&
288 ((infostring != NULL) && overlap (INFOX, INFOY,
289 INFOX+INFOWIDTH, INFOY+INFOHEIGHT,
290 updateRect))) {
291 RECT infoRect;
292 infoRect.left = INFOX;
293 infoRect.top = INFOY;
294 infoRect.right = INFOX+INFOWIDTH;
295 infoRect.bottom = INFOY+INFOHEIGHT;
296 FillRect(pdc, &infoRect, (HBRUSH)GetStockObject(WHITE_BRUSH));
297 DrawText(pdc, infostring, -1, &infoRect, DT_CENTER);
298 }
299
300 // update the logo (always)
301 BitBlt (pdc, LOGOX, LOGOY, LOGOX+LOGOWIDTH, LOGOY+LOGOHEIGHT,
302 logodc, 0, 0, SRCCOPY);
303}
304
305
306void handle_painting (HWND Window) {
307 HDC pdc; PAINTSTRUCT ps;
308 pdc = BeginPaint(Window, &ps);
309
310 paint_window (pdc, ps.rcPaint);
311
312 EndPaint(Window, &ps);
313}
314
315
316// returns 1 on success, 0 otherwise
317int enter_library (HWND Window) {
318 int res;
319
320 // get the url and attempt to start a browser
321 char *localname = GetLocalName(NULL);
322 if (have_networking) {
323 text_t url = "http://" + text_t(localname);
324 if (gsdl_port_num != 80)
325 url += ":" + text_t(gsdl_port_num);
326
327 url += gsdl_enterlib;
328
329 // add a unique ending so it will always result in a request
330 text_t::const_iterator it =
331 findchar (gsdl_enterlib.begin(), gsdl_enterlib.end(), '?');
332 if (it == gsdl_enterlib.end()) url.push_back ('?');
333 else url.push_back ('&');
334 int tcount = GetTickCount();
335 url += "uq=" + text_t(tcount);
336
337 // remember the library access number for later proxy checking
338 enterlib_libaccessnum = libaccessnum;
339
340 // do a quick check to make sure we're using netscape when
341 // we should be (it might have been just installed)
342 if (netscapeneeded) gsdl_check_browser_settings (netscapeneeded);
343
344 char *cstr_url = url.getcstr();
345 if (strlen (startbrowserdir) <= 0) {
346 res = startbrowser (cstr_url, gsdl_browser_exe, NULL);
347
348 } else res = startbrowser (cstr_url, gsdl_browser_exe, startbrowserdir);
349
350 delete cstr_url;
351
352 }
353
354 if (res == SB_NOERROR) {
355 // success !!
356
357 // remember the time the browser was started for later proxy checking
358 if (have_networking) enterlib_time = GetTickCount();
359
360 return 1;
361 }
362
363 // no browser was started
364 enterlib_libaccessnum = -1;
365
366 if ((res == SB_FAIL_BADFORMAT) || (res == SB_FAIL_NOTFOUND)) {
367 if (!netscapeneeded) { // any browser
368 MessageBox(Window,
369 "Failed to start your chosen browser. It seems that your\n"
370 "chosen browser has been removed or corrupted.\n"
371 "Please check you browser choice by going to the\n"
372 "'Settings...' item under the 'File' menu.",
373 "Greenstone Digital Library Software", MB_OK);
374 } else { // netscape used
375 MessageBox(Window,
376 "Failed to start Netscape. It seems that Netscape has\n"
377 "been removed or corrupted. You need Netscape\n"
378 "installed to use the Greenstone Digital Library\n"
379 "software on non-networked machines.",
380 "Greenstone Digital Library Software", MB_OK);
381 }
382
383 } else {
384 MessageBox(Window,
385 "Failed to start your browser. This may have been\n"
386 "because there was not enough memory available. Shut\n"
387 "down all other applications you have running, and\n"
388 "try again.",
389 "Greenstone Digital Library Software", MB_OK);
390 }
391
392 return 0; // failed
393}
394
395
396void install_netscape (HWND Window) {
397 char installpath[256];
398
399 // try to find the browser directory
400 char *gsdlhome = gsdl_gsdlhome.getcstr();
401 strcpy (installpath, gsdlhome); // use gsdlhome to find the CD-ROM drive...
402 delete gsdlhome;
403
404 // remove any slashes from the pathname
405 int len = strlen (installpath);
406 while ((len > 0) && ((installpath[len-1] == '\\') || (installpath[len-1] == '/'))) {
407 len--;
408 }
409 // remove '\gsdl'
410 len = len - 5;
411 installpath[len] = '\0';
412
413 strcat (installpath, "\\netscape\\");
414
415 // check this directory
416 if (!cstrcheckdir(installpath)) {
417 return;
418 }
419
420 // get the operating system information
421 OSVERSIONINFO osver;
422 memset(&osver, 0, sizeof(OSVERSIONINFO));
423 osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
424 GetVersionEx(&osver);
425
426 // get the install program for this operating system
427 if (osver.dwPlatformId == VER_PLATFORM_WIN32s) {
428 strcat (installpath, "n16e405.exe");
429 } else {
430 strcat (installpath, "n32e405.exe");
431 }
432
433 // run the install program
434 int res = WinExec (installpath, SW_SHOW);
435 if (res == 0) {
436 // out of resources or memory
437 MessageBox (Window,
438 "Did not have enough resources or memory to run the\n"
439 "install program. Try shutting down all other programs\n"
440 "and trying again.",
441 "Greenstone Digital Library Software",
442 MB_OK|MB_APPLMODAL);
443
444 } else if (res == ERROR_BAD_FORMAT) {
445 // executable image is corrupt -- ????
446 MessageBox (Window,
447 "The install program seems to be corrupt.",
448 "Greenstone Digital Library Software",
449 MB_OK|MB_APPLMODAL);
450
451 } else if ((res == ERROR_FILE_NOT_FOUND) || (res == ERROR_PATH_NOT_FOUND)) {
452 // couldn't find the executable -- ????
453 MessageBox (Window,
454 "Could not find the install program. Try installing\n"
455 "Netscape from the Greenstone Digital Library\n"
456 "software's install program.",
457 "Greenstone Digital Library Software",
458 MB_OK|MB_APPLMODAL);
459 }
460}
461
462void open_help () {
463 char topdir[256], cmd[256];
464
465 // try to find the browser directory
466 char *gsdlhome = gsdl_gsdlhome.getcstr();
467 strcpy (topdir, gsdlhome); // use gsdlhome to find the CD-ROM drive...
468 delete gsdlhome;
469 strcpy (cmd, "notepad ");
470
471 // remove any slashes from the pathname
472 int len = strlen (topdir);
473 while ((len > 0) && ((topdir[len-1] == '\\') || (topdir[len-1] == '/'))) {
474 len--;
475 }
476 // remove the '\gsdl'
477 len = len - 5;
478 topdir[len] = '\0';
479
480 strcat (topdir, "\\README.txt");
481 strcat (cmd, topdir);
482
483 WinExec (cmd, SW_SHOW);
484}
485
486
487long __stdcall WndProc(HWND Window, UINT Message, WPARAM WParam, LPARAM LParam) {
488 switch(Message) {
489 // Constant Messages
490 case WM_CREATE:
491 break;
492
493 case WM_COMMAND:
494 if ((GoButton != NULL) && ((HWND)LParam == GoButton)) {
495 // attempt to start a browser
496 if (enter_library (Window) && !gsdl_show_console)
497 ShowWindow(Window,SW_MINIMIZE);
498
499 } else if ((Enter != NULL) && ((HWND)LParam == Enter)) {
500 init_done = 1;
501 init_type = 1;
502
503 } else if ((EnterRestricted != NULL) && ((HWND)LParam == EnterRestricted)) {
504 init_done = 1;
505 init_type = 0;
506
507 } else if ((InfoRestricted != NULL) && ((HWND)LParam == InfoRestricted)) {
508 MessageBox (NULL, "The Greenstone system automatically determines whether your computer has\n"
509 "network software installed or is connected to a network. It operates correctly\n"
510 "under any of these conditions.\n\n"
511 "The restricted version is intended for use when the standard one\n\n"
512 " (a) causes an unwanted telephone dialup operation;\n"
513 " (b) fails to run because network software is installed, but installed\n"
514 " incorrectly.\n\n"
515 "The restricted version only works with Netscape (not Internet Explorer).\n\n"
516 "Unless these problems arise, you should always use the standard version\n"
517 "(press the 'Enter Library' button).\n",
518 "Greenstone Digital Library Software",
519 MB_OK | MB_ICONINFORMATION | MB_APPLMODAL);
520
521 } else {
522 switch (LOWORD(WParam)) {
523 case ID_PROJECT_SETTINGS:
524 Settings_Dialog(Window, netscapeneeded);
525 break;
526 case ID_INSTALL_NETSCAPE:
527 install_netscape(Window);
528 break;
529 case IDHELP:
530 open_help();
531 break;
532 case ID_PROJECT_EXIT:
533 finish_up();
534 break;
535 default:
536 break;
537 }
538 }
539 break;
540
541 case WM_PAINT:
542 handle_painting(Window);
543 break;
544
545 case HTTP_SERVER_MSG:
546 ProcessHTTPServerMsg(WParam, LParam);
547 break;
548
549 case WM_DESTROY:
550 finish_up();
551 break;
552
553 default:
554 //Unhandled Messages end up here (DefWindowProc)
555 return DefWindowProc(Window, Message, WParam, LParam);
556 }
557
558 return(0);
559}
560
561// returns 0 if successful,
562// otherwise a WSA error number
563int tryinitnetwork (HANDLE Instance, HWND MsgWindow, char *path) {
564 // try to load winsock
565 int err = d_LoadWinsock (path);
566
567 if (err == D_NOERROR) {
568 // next, try to init netio
569 err = InitNetIO();
570
571 if (err == 0) {
572 // next, try to start the http server
573 err = StartHTTPServer(MsgWindow);
574
575 if (err == 0) {
576 // finally, get the host name (no error value
577 // is returned from this function)
578 GetLocalName((HINSTANCE)Instance);
579
580 } else {
581 // couldn't start the http server,
582 // deinit netio and unload winsock
583 CleanUpNetIO();
584 d_UnloadWinsock();
585 }
586
587 } else {
588 // couldn't init netio, unload winsock
589 d_UnloadWinsock();
590 }
591
592 } else {
593 // couldn't load winsock
594 err = WSASYSNOTREADY;
595 }
596
597 return err;
598}
599
600
601// inits all the network functionality
602// returns 0 if an unrecoverable error occurred,
603// and 1 if everything successfully initialised.
604int initnetwork (HANDLE Instance, HWND MsgWindow) {
605 OSVERSIONINFO osver;
606
607 // get the operating system information
608 memset(&osver, 0, sizeof(OSVERSIONINFO));
609 osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
610 GetVersionEx(&osver);
611
612 // first try to initialise the network with system installed
613 // networking software
614 startbrowserdir[0] = '\0';
615 netscapeneeded = 0;
616 int err = 1;
617 if (init_type == 1) err = tryinitnetwork (Instance, MsgWindow, NULL);
618
619 // if an error occurred, try again with billsock
620 if (err != 0) {
621 // get the path of billsock (current directory + ("net16" | "net32"))
622 char winsockpath[1024]; // HARD LIMIT!!!!
623
624 find_location();
625 strcpy (winsockpath, data_location);
626
627 // remove all the slashes at the end of billpath
628 int len = strlen (winsockpath);
629 while ((len > 0) && ((winsockpath[len-1] == '\\') || (winsockpath[len-1] == '/'))) {
630 len--;
631 }
632 winsockpath[len] = '\0';
633
634 if (osver.dwPlatformId == VER_PLATFORM_WIN32s)
635 strcat (winsockpath, "\\net16\\");
636 else {
637 strcat (winsockpath, "\\net32\\");
638 strcpy (startbrowserdir, winsockpath);
639 }
640
641 // try again
642 err = tryinitnetwork (Instance, MsgWindow, winsockpath);
643
644 if (err == 0) {
645 // we will need to use netscape on 95/98/NT machines
646 if (osver.dwPlatformId != VER_PLATFORM_WIN32s) {
647 netscapeneeded = 1;
648 // make sure the browser state is in step with the network condition
649 gsdl_check_browser_settings (netscapeneeded);
650 }
651
652 // check to see if a browser is running
653 if (browserrunning(gsdl_browser_exe) == NO_ERROR) {
654 MessageBox (NULL,
655 "The Greenstone Digital Library software has detected a\n"
656 "running browser. To let our networking software\n"
657 "correctly initialize, please shut down your browser\n"
658 "and restart the Greenstone Digital Library software.",
659 "Greenstone Digital Library Software", MB_OK|MB_APPLMODAL);
660 PostMessage(MsgWindow,WM_CLOSE,0,0);
661 finish_up(); // will unload winsock
662 exit(0); // nothing more to do
663 }
664 }
665 }
666
667 // if an error occurred display a nice error message
668 if (err != 0) {
669
670 // WSASYSNOTREADY Couldn't load winsock
671 // WSAVERNOTSUPPORTED The version of Windows Sockets support requested
672 // is not provided by this particular Windows Sockets implementation.
673 // WSAEINVAL The Windows Sockets version specified by the application
674 // is not supported by this DLL.
675 // WSAEPROTONOSUPPORT The specified protocol is not supported.
676 // WSAEPROTOTYPE The specified protocol is the wrong type for this socket.
677 // WSAESOCKTNOSUPPORT The specified socket type is not supported in
678 // this address family.
679 // WSANOTINITIALISED A successful WSAStartup must occur before
680 // using this function.
681 // WSAENETDOWN The Windows Sockets implementation
682 // has detected that the network subsystem has failed.
683 // WSAEADDRINUSE The specified address
684 // is already in use. (See the SO_REUSEADDR socket option under setsockopt.)
685 // WSAEFAULT The namelen argument is too small (less
686 // than the size of a struct sockaddr).
687 // WSAEINPROGRESS A blocking Windows Sockets call is in progress.
688 // WSAEAFNOSUPPORT The specified address family is not supported
689 // by this protocol.
690 // WSAENOBUFS Not enough buffers available, too many connections.
691 // WSAENOTSOCK The descriptor is not a socket.
692 // WSAEISCONN The socket is already connected.
693 // WSAEMFILE No more file descriptors are available.
694 // WSAEOPNOTSUPP The referenced socket is not of a type that
695 // supports the listen operation.
696
697 // get a text version of the error number
698 char errstr[256];
699
700 switch (err) {
701 case WSASYSNOTREADY: strcpy(errstr, "WSASYSNOTREADY");
702 break;
703 case WSAVERNOTSUPPORTED: strcpy (errstr, "WSAVERNOTSUPPORTED");
704 break;
705 case WSAEINVAL: strcpy (errstr, "WSAEINVAL");
706 break;
707 case WSAEPROTONOSUPPORT: strcpy (errstr, "WSAEPROTONOSUPPORT");
708 break;
709 case WSAEPROTOTYPE: strcpy (errstr, "WSAEPROTOTYPE");
710 break;
711 case WSAESOCKTNOSUPPORT: strcpy (errstr, "WSAESOCKTNOSUPPORT");
712 break;
713 case WSANOTINITIALISED: strcpy (errstr, "WSANOTINITIALISED");
714 break;
715 case WSAEFAULT: strcpy (errstr, "WSAEFAULT");
716 break;
717 case WSAEAFNOSUPPORT: strcpy (errstr, "WSAEAFNOSUPPORT");
718 break;
719 case WSAENOTSOCK: strcpy (errstr, "WSAENOTSOCK");
720 break;
721 case WSAEISCONN: strcpy (errstr, "WSAEISCONN");
722 break;
723 case WSAEOPNOTSUPP: strcpy (errstr, "WSAEOPNOTSUPP");
724 break;
725 case WSAENETDOWN: strcpy (errstr, "WSAENETDOWN");
726 break;
727 case WSAEADDRINUSE: strcpy (errstr, "WSAEADDRINUSE");
728 break;
729 case WSAEINPROGRESS: strcpy (errstr, "WSAEINPROGRESS");
730 break;
731 case WSAENOBUFS: strcpy (errstr, "WSAENOBUFS");
732 break;
733 case WSAEMFILE: strcpy (errstr, "WSAEMFILE");
734 break;
735 default: sprintf (errstr, "WSA ERROR: %i", err);
736 break;
737 }
738
739 // create a nice error message
740 char message[2048];
741
742 switch (err) {
743 case WSAEADDRINUSE:
744 // couldn't bind socket
745 sprintf (message, "Could not find a free socket.", errstr);
746 break;
747
748 default:
749 // cannot init winsock
750 sprintf (message, "Could not initialize the network\n"
751 " (Reason: %s).", errstr);
752 break;
753 }
754
755 strcat (message, "\n\n"
756 "Please submit a bug report using the support.htm file\n"
757 "on the CD-ROM.");
758
759 MessageBox (NULL, message, "Greenstone Digital Library Software", MB_OK);
760 }
761
762 return (err == 0);
763}
764
765
766void log_computer_info () {
767 char tmpstr[1024];
768
769 // get various information about this computer
770 if (gsdl_keep_log || gsdl_show_console) {
771 // get operating system information
772 OSVERSIONINFO osver;
773 osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
774
775 if (GetVersionEx(&osver)) {
776 if (osver.dwPlatformId == VER_PLATFORM_WIN32s) {
777 log_message ("Platform: win32s\n");
778 } else if (osver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) {
779 log_message ("Platform: windows 95\n");
780 } else if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT) {
781 log_message ("Platform: windows NT\n");
782 }
783
784 sprintf (tmpstr, "MajorVersion: %i\n", (int)osver.dwMajorVersion);
785 log_message(tmpstr);
786 sprintf (tmpstr, "MinorVersion: %i\n", (int)osver.dwMinorVersion);
787 log_message(tmpstr);
788 sprintf (tmpstr, "BuildNumber: %i\n", (int)osver.dwBuildNumber);
789 log_message(tmpstr);
790 sprintf (tmpstr, "CSDVersion: %s\n\n", osver.szCSDVersion);
791 log_message(tmpstr);
792 }
793
794 // get memory information
795 MEMORYSTATUS memstatus;
796 memstatus.dwLength = sizeof(MEMORYSTATUS);
797 GlobalMemoryStatus(&memstatus);
798
799 sprintf (tmpstr, "TotalPhys: %i Meg\n", (int)(memstatus.dwTotalPhys/1024/1024));
800 log_message (tmpstr);
801 sprintf (tmpstr, "AvailPhys: %i Meg\n", (int)(memstatus.dwAvailPhys/1024/1024));
802 log_message (tmpstr);
803 sprintf (tmpstr, "TotalPageFile: %i Meg\n", (int)(memstatus.dwTotalPageFile/1024/1024));
804 log_message (tmpstr);
805 sprintf (tmpstr, "AvailPageFile: %i Meg\n", (int)(memstatus.dwAvailPageFile/1024/1024));
806 log_message (tmpstr);
807 sprintf (tmpstr, "TotalVirtual: %i Meg\n", (int)(memstatus.dwTotalVirtual/1024/1024));
808 log_message (tmpstr);
809 sprintf (tmpstr, "AvailVirtual: %i Meg\n\n", (int)(memstatus.dwAvailVirtual/1024/1024));
810 log_message (tmpstr);
811
812 // log the version number
813 log_message("GSDL version: " VERSIONSTRING "\n");
814 }
815
816}
817
818
819int __stdcall WinMain(HINSTANCE Instance, HINSTANCE /*PrevInstance*/, LPSTR CmdLineStr, int /*CmdShow*/) {
820 HWND MainWindow; MSG Message; WNDCLASS MainClass;
821
822 //Create a window class
823 MainClass.style = CS_HREDRAW | CS_VREDRAW;
824 MainClass.lpfnWndProc = WndProc;
825 MainClass.cbClsExtra = 0;
826 MainClass.cbWndExtra = 0;
827 MainClass.hInstance = Instance;
828 MainClass.hIcon = LoadIcon(Instance, MAKEINTRESOURCE(TRAY_ICON));
829 MainClass.hCursor = LoadCursor(NULL, IDC_ARROW);
830 MainClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
831 MainClass.lpszMenuName = MAKEINTRESOURCE(Main_Menu);
832 MainClass.lpszClassName = "Greenstone Digital Library Software";
833 if (!RegisterClass(&MainClass))
834 return 0;
835
836
837 // Load various bitmaps
838 coltitlebitmap = LoadBitmap (Instance, MAKEINTRESOURCE(GSDL_COL_TITLE));
839 logobitmap= LoadBitmap (Instance, MAKEINTRESOURCE(GSDL_LOGO));
840
841 // Create the main window
842 MainWindow = CreateWindow("Greenstone Digital Library Software",
843 "Greenstone Digital Library Software",
844 WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU |
845 WS_MINIMIZEBOX,
846 CW_USEDEFAULT, CW_USEDEFAULT,
847 MAINWINDOWWIDTH + WASTEWIDTH,
848 MAINWINDOWHEIGHT + WASTEHEIGHT,
849 NULL, NULL, Instance, NULL);
850
851 text_rect.left = 0;
852 text_rect.top = VERSIONY+VERSIONHEIGHT + 5;
853 text_rect.right = MAINWINDOWWIDTH;
854 text_rect.bottom = LOGOY-SPACERWIDTH;
855
856 window_state = undefined_window;
857
858 ShowWindow(MainWindow, SW_SHOW);
859 set_location(CmdLineStr);
860
861 // get ready to draw the main window
862 RECT windowRect;
863 GetClientRect (MainWindow, &windowRect);
864 HDC pdc = GetDC (MainWindow);
865
866 // retrieve and save the text metrics
867 TEXTMETRIC tm;
868 GetTextMetrics(pdc, &tm);
869 line_spacing = tm.tmHeight + tm.tmExternalLeading;
870 GSDL_Window = MainWindow;
871
872 // init various modules
873 read_settings (0); // don't know if netscape is needed at this point
874
875 if (!gsdl_auto_enter) {
876
877 // add the select version checkbox
878 Enter = CreateWindow("BUTTON", // predefined class
879 "Enter Library", // button text
880 WS_VISIBLE | WS_CHILD | WS_TABSTOP | BS_DEFPUSHBUTTON, // styles
881 ENTERBUTTONX, // starting x position
882 ENTERBUTTONY, // starting y position
883 ENTERBUTTONWIDTH, // button width
884 ENTERBUTTONHEIGHT, // button height
885 MainWindow, // parent window
886 NULL, // No menu
887 Instance,
888 NULL); // pointer not needed
889
890 EnterRestricted = CreateWindow("Button", // predefined class
891 "Restricted Version", // button text
892 WS_VISIBLE | WS_CHILD | WS_TABSTOP | BS_PUSHBUTTON, // styles
893 ALTERNATIVEBUTTONX, // starting x position
894 ALTERNATIVEBUTTONY, // starting y position
895 ALTERNATIVEBUTTONWIDTH-(INFOBUTTONWIDTH+SPACERWIDTH), // button width
896 ALTERNATIVEBUTTONHEIGHT, // button height
897 MainWindow, // parent window
898 (HMENU)NULL, // No menu
899 Instance,
900 NULL); // pointer not needed
901
902 InfoRestricted = CreateWindow("Button", // predefined class
903 NULL,
904 WS_VISIBLE | WS_CHILD | WS_TABSTOP | BS_BITMAP, // styles
905 ALTERNATIVEBUTTONWIDTH-INFOBUTTONWIDTH+SPACERWIDTH, // starting x position
906 ALTERNATIVEBUTTONY, // starting y position
907 INFOBUTTONWIDTH, // button width
908 ALTERNATIVEBUTTONHEIGHT, // button height
909 MainWindow, // parent window
910 (HMENU)NULL, // No menu
911 Instance,
912 NULL); // pointer not needed
913
914 HANDLE i_icon = LoadImage (Instance, MAKEINTRESOURCE(GSDL_ICBMP), IMAGE_BITMAP,
915 INFOBUTTONWIDTH-4, ALTERNATIVEBUTTONHEIGHT-4, LR_DEFAULTCOLOR);
916 SendMessage (InfoRestricted, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)i_icon);
917
918 SetFocus (Enter);
919
920 enterstring = strenterlib;
921 paint_window (pdc, windowRect);
922
923 // message loop for init buttons
924 while (!init_done) {
925 if (PeekMessage(&Message, NULL, 0, 0, PM_REMOVE)) {
926 if (Message.message == WM_QUIT) return Message.wParam;
927 if (!IsDialogMessage (MainWindow, &Message)) {
928 TranslateMessage(&Message); /* translate keyboard messages */
929 DispatchMessage(&Message); /* return control to Windows NT */
930 }
931 } else {
932 Sleep (1);
933 }
934 }
935
936 // don't want these buttons anymore
937 DestroyWindow (Enter);
938 DestroyWindow (EnterRestricted);
939 DestroyWindow (InfoRestricted);
940
941 enterstring = strnothing;
942 paint_window (pdc, windowRect);
943
944 } else {
945 // auto enter is enabled - start up standard version
946 init_type = 1;
947 init_done = 1;
948 }
949
950 // draw the main window containing an init message
951 infostring = strinit;
952 paint_window (pdc, windowRect);
953 DWORD lastcheck = GetTickCount();
954
955 have_networking = initnetwork (Instance, MainWindow);
956 if (!have_networking) {
957 MessageBox(NULL,
958 "Failed to initialize networking.",
959 "Greenstone Digital Library Software",MB_OK|MB_SYSTEMMODAL);
960 exit (0);
961 }
962
963 if (!gsdl_init()) // quit if can't initialise the library correctly
964 exit (0);
965 initstartbrowser();
966 log_computer_info ();
967
968 // show the initialising message for at least 1 second
969 while (DiffTickCounts (lastcheck, GetTickCount()) < 1000) {
970 Sleep (1);
971 }
972
973 // attempt to start a browser
974 if (gsdl_show_console) infostring = strnothing;
975 else infostring = strsb;
976 paint_window (pdc, windowRect);
977 lastcheck = GetTickCount();
978 if (enter_library (MainWindow) && !gsdl_show_console) {
979 // stay maximised for at least 1 second
980 while (DiffTickCounts (lastcheck, GetTickCount()) < 1000) Sleep (1);
981 ShowWindow(MainWindow,SW_MINIMIZE);
982 }
983
984 // add the "restart library" button
985 GoButton = CreateWindow("BUTTON", // predefined class
986 "Restart Library", // button text
987 WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, // styles
988 RESTARTBUTTONX, // starting x position
989 RESTARTBUTTONY, // starting y position
990 RESTARTBUTTONWIDTH, // button width
991 RESTARTBUTTONHEIGHT, // button height
992 MainWindow, // parent window
993 NULL, // No menu
994 Instance,
995 NULL); // pointer not needed
996
997 infostring = strrestartlib;
998 paint_window (pdc, windowRect);
999
1000 // release the DC used to display the init messages
1001 ReleaseDC (MainWindow, pdc);
1002
1003 //Message loop
1004 lastcheck = GetTickCount();
1005 int seenbrowser = 0; // if we see a browser then it disappears
1006 // we will ask if they want to close the
1007 // the library down
1008 char last_gsdl_browser_exe[MAX_FILENAME_SIZE]; // need to notice when the
1009 // browser setting changes
1010 strcpy (last_gsdl_browser_exe, gsdl_browser_exe);
1011
1012 for (;;) {
1013 if (PeekMessage(&Message, NULL, 0, 0, PM_REMOVE)) {
1014 if (Message.message == WM_QUIT) break;
1015 if (!IsDialogMessage (MainWindow, &Message)) {
1016 TranslateMessage(&Message); /* translate keyboard messages */
1017 DispatchMessage(&Message); /* return control to Windows NT */
1018 }
1019
1020 } else {
1021 if (DiffTickCounts (lastcheck, GetTickCount()) > 500) {
1022 // make sure the browser hasn't changed
1023 if (strcmp (last_gsdl_browser_exe, gsdl_browser_exe) != 0) {
1024 seenbrowser = 0;
1025 strcpy (last_gsdl_browser_exe, gsdl_browser_exe);
1026 }
1027
1028 // do check
1029 lastcheck = GetTickCount();
1030 if (browserrunning(gsdl_browser_exe) == NO_ERROR) {
1031 // we were able to connect to a browser
1032 seenbrowser = 1;
1033
1034 // see if the enter library button has been pressed
1035 // with nothing happening for 20 seconds
1036 if ((enterlib_libaccessnum >= 0) &&
1037 (enterlib_libaccessnum == libaccessnum) &&
1038 (DiffTickCounts (enterlib_time, GetTickCount()) > 20000)) {
1039 // something could be wrong!! (most likely cause is a proxy)
1040 MessageBox(NULL,
1041 "Your browser does not seem to be responding to the 'Enter Library'\n"
1042 "request. Try turning off all proxy servers in your browser settings.",
1043 "Greenstone Digital Library Software",MB_OK|MB_SYSTEMMODAL);
1044 enterlib_libaccessnum = -1;
1045 }
1046
1047
1048 } else {
1049 // no browser was found
1050
1051 if (seenbrowser) {
1052 // we have seen a browser in the past
1053 if (MessageBox(NULL,
1054 "The Greenstone Digital Library software has noticed that you\n"
1055 "shut down your browser. Would you also like to shut down the\n"
1056 "Greenstone Digital Library software?",
1057 "Greenstone Digital Library Software",MB_YESNO|MB_SYSTEMMODAL) == IDYES)
1058 PostMessage(MainWindow,WM_CLOSE,0,0);
1059 }
1060 seenbrowser = 0;
1061 }
1062 }
1063
1064 Sleep (1); // millisecond
1065 }
1066 }
1067
1068 return Message.wParam;
1069}
Note: See TracBrowser for help on using the repository browser.