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

Last change on this file since 2935 was 2935, checked in by sjboddie, 22 years ago

Added Greenstone version number to admin pages

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