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

Last change on this file since 1293 was 1292, checked in by sjboddie, 24 years ago

* empty log message *

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