www.pudn.com > speakfs72.zip > DIALOGS.C, change:2002-01-05,size:48165b


/* 
 
				Dialogue procedures 
 
*/ 
 
#include "netfone.h" 
 
typedef struct _NEW_HOST_PARAMS { 
    LPSTR pszHostName; 
    LPIN_ADDR paddr; 
    unsigned short *port_no; 
    HANDLE hAsync; 
    ULONG laddr; 
    BYTE bBuffer[MAXGETHOSTSTRUCT]; 
} NEW_HOST_PARAMS, FAR *LPNEW_HOST_PARAMS; 
 
NEW_HOST_PARAMS NewHostParams;          // Parameters for NewHost dialog 
 
//	SESSIONKEYGENERATE  --  Generate a random session key 
 
void sessionKeyGenerate(LPSTR key, BOOL binary) 
{ 
	int j, k; 
	char s[256]; 
    struct MD5Context md5c; 
    char md5key[16], md5key1[16]; 
    POINT p; 
	MEMORYSTATUS ms; 
	 
	/*	The following gets all kind of information likely 
		to vary from moment to moment and uses it as the initial 
		seed for the random number generator.  If any of these 
		causes porting problems in the future, just delete them.  */ 
	 
    wsprintf(s, Format(28), GetTickCount()); 
    wsprintf(s + strlen(s), Format(28), time(NULL)); 
    gethostname(s + strlen(s), 256); 
    wsprintf(s + strlen(s), Format(29), GetActiveWindow()); 
    wsprintf(s + strlen(s), Format(28), GetFreeSpace(0)); 
	ms.dwLength = sizeof(MEMORYSTATUS); 
	GlobalMemoryStatus(&ms); 
	wsprintf(s + strlen(s), Format(28), ms.dwMemoryLoad);  
	wsprintf(s + strlen(s), Format(28), ms.dwAvailPhys);  
	wsprintf(s + strlen(s), Format(28), ms.dwAvailPageFile);  
    GetCursorPos(&p); 
    wsprintf(s + strlen(s), Format(30), p.x, p.y);  
    MD5Init(&md5c); 
    MD5Update(&md5c, s, strlen(s)); 
    MD5Final(md5key, &md5c); 
    wsprintf(s + strlen(s), Format(28), (time(NULL) + 65121) ^ 0x375F); 
    MD5Init(&md5c); 
    MD5Update(&md5c, s, strlen(s)); 
    MD5Final(md5key1, &md5c); 
#ifdef CRYPTO     
    init_idearand(md5key, md5key1, time(NULL)); 
#endif     
    for (j = k = 0; j < 16; j++) { 
#ifdef CRYPTO     
        unsigned char rb = idearand(); 
#else 
		unsigned char rb = (unsigned char) (md5key[j] ^ md5key1[j]);         
#endif         
         
        if (binary) { 
        	key[j] = (char) rb; 
        } else { 
#define Rad16(x) ((x) + 'A') 
	        key[k++] = Rad16((rb >> 4) & 0xF); 
	        key[k++] = Rad16(rb & 0xF); 
	        if (j & 1) { 
	            key[k++] = '-'; 
	        } 
        } 
    } 
    if (!binary) { 
    	key[--k] = 0; 
    } 
#ifdef CRYPTO     
    close_idearand(); 
#endif     
} 
 
/*  MAKEINTERNALENCRYPTIONKEYS  --  Create actual encryption keys from user 
									specified keys.  */ 
 
int makeInternalEncryptionKeys(HWND hwnd, LPCLIENT_DATA d) 
{ 
#ifdef IP_MAX_MEMBERSHIPS 
	if (IN_MULTICAST(d->inetSock.sin_addr.s_addr)) { 
	 
		/* Windows 95 WINSOCK bombs with an "out of range address" 
		   when a char is passed as the multicast TTL optval, as 
		   one does on Unix and which works fine with Trumpet 
		   Winsock.  Work-around by allowing the user to send either 
		   a char or an int.  Trumpet happens to work OK if you pass 
		   an int, but there's probably some other WINSOCK that won't 
		   accept a length of 2 for this argument. */ 
	 
		if (waNetMultiTTLisChar) { 
			unsigned char scope = d->multicast_scope; 
		 
			if (setsockopt(d->sReply, IPPROTO_IP, IP_MULTICAST_TTL, 
							(char *) &scope, sizeof scope) == -1 || 
				setsockopt(d->sControl, IPPROTO_IP, IP_MULTICAST_TTL, 
							(char *) &scope, sizeof scope) == -1) { 
	            int serr = WSAGetLastError(); 
	             
		        MsgBox(hwnd, MB_ICONSTOP | MB_OK, Format(38), 
		                d->szHost, serr, SockerrToString(serr)); 
			} 
		} else { 
			int scope = d->multicast_scope; 
		 
			if (setsockopt(d->sReply, IPPROTO_IP, IP_MULTICAST_TTL, 
							(char *) &scope, sizeof scope) == -1 || 
				setsockopt(d->sControl, IPPROTO_IP, IP_MULTICAST_TTL, 
							(char *) &scope, sizeof scope) == -1) { 
	            int serr = WSAGetLastError(); 
	             
		        MsgBox(hwnd, MB_ICONSTOP | MB_OK, Format(38), 
		                d->szHost, serr, SockerrToString(serr)); 
			} 
		} 
	} 
#endif	 
 
#ifdef CRYPTO 
	if ((d->deskey[0] = d->rtpdeskey[0] = 
		 d->vatdeskey[0] = (_fstrlen(d->desKeyString) > 0)) == TRUE) { 
		int j; 
	    struct MD5Context md5c; 
	    char md5key[16], algorithm[16]; 
						 
	    MD5Init(&md5c); 
	    MD5Update(&md5c, d->desKeyString, _fstrlen(d->desKeyString)); 
	    MD5Final(md5key, &md5c); 
	    for (j = 0; j < 8; j++) { 
	        d->deskey[j + 1] = (char) 
	                      ((md5key[j] ^ md5key[j + 8]) & 0x7F); 
	    } 
	    des_string_to_key(d->desKeyString, (des_cblock FAR *) (d->vatdeskey + 1)); 
		string_DES_key(d->desKeyString, (LPBYTE) d->rtpdeskey + 1, algorithm); 
        if (_fstrcmp(algorithm, rstring(IDS_T_DES_CBC)) != 0) { 
	        MsgBox(hwnd, MB_ICONSTOP | MB_OK, Format(68), (LPSTR) algorithm, 
	        	   (LPSTR) rstring(IDS_T_DES_CBC)); 
		} 
	} 
	 
	if ((d->ideakey[0] = (_fstrlen(d->ideaKeyString) > 0)) == TRUE) { 
	    struct MD5Context md5c; 
						 
	    MD5Init(&md5c); 
	    MD5Update(&md5c, d->ideaKeyString, _fstrlen(d->ideaKeyString)); 
		MD5Final(d->ideakey + 1, &md5c); 
	} 
	 
	if ((d->blowfish_spec = (_fstrlen(d->blowfishKeyString) > 0)) == TRUE) { 
	    struct MD5Context md5c; 
		unsigned char bfvec[16]; 
						 
	    MD5Init(&md5c); 
	    MD5Update(&md5c, d->blowfishKeyString, _fstrlen(d->blowfishKeyString)); 
		MD5Final(bfvec, &md5c); 
		BF_set_key(&(d->blowfishkey), 16, bfvec); 
	} 
	 
	if (d->opgpUserList[0]) { 
		char cmd[256]; 
		HFILE kfile; 
		char tp[MAX_PATH]; 
 
		GetTempPath(sizeof tp, tp);  
	    sessionKeyGenerate(d->opgpkey + 1, TRUE); 
	    d->opgpkey[0] = FALSE; 
		GetTempFileName(tp, "PK", 0, d->opgpFileName); 
	 
        kfile = _lcreat(d->opgpFileName, 0); 
		if (kfile == HFILE_ERROR) { 
            MessageBox(hwnd, rstring(IDS_T_PGP_OPEN_SESSION_ERR), 
            	rstring(IDS_T_PGP_ENCODING_TITLE), MB_ICONEXCLAMATION | MB_OK); 
		} else { 
			UINT execStat = 0; 
		 
			_lwrite(kfile, "K", 1); 
			_lwrite(kfile, d->opgpkey + 1, 16); 
			_lclose(kfile); 
			 
			/*	First try to run PGP via the PIF in our own directory.  This 
				guarantees it's run with the modes we've chosen, such as 
				in a window rather than full-screen.  */ 
			 
			if (GetModuleFileName(hInst, cmd, sizeof cmd) > 0) { 
				char *cp = cmd + strlen(cmd); 
				 
				while (cp >= cmd && *cp != '\\' && *cp != ':') { 
					cp--; 
				} 
				cp[1] = 0; 
				wsprintf(cmd + strlen(cmd), Format(53), 
						 d->opgpFileName, d->opgpUserList + 1); 
				execStat = WinExec(cmd, SW_SHOW);  
			} 
 
			/*	If that didn't work, attempt to run PGP by straight path 
				search using the default modes.  */ 
				 
			if (execStat < 32) {                        
            	wsprintf(cmd, Format(31), d->opgpFileName, d->opgpUserList + 1); 
            	execStat = WinExec(cmd, SW_SHOW); 
            } 
	             
            //	Set timer to poll for completion of encoding 
	             
            if (execStat >= 32) { 
	            d->opgpFileName[_fstrlen(d->opgpFileName) - 3] = 0; 
	            _fstrcat(d->opgpFileName, "PGP"); 
	            SetTimer(hwnd, 4, 1000, NULL); 
	        } else { 
	        	wsprintf(cmd + strlen(cmd), Format(51), execStat); 
	        	MessageBox(hwnd, cmd, rstring(IDS_T_CANT_INVOKE_PGP_ENCODE), 
			   		MB_OK | MB_ICONEXCLAMATION); 
	        } 
		} 
	} 
	 
	if (d->otpFileName[0]) { 
		HFILE fp = _lopen(d->otpFileName, OF_READ); 
		if (fp == HFILE_ERROR) { 
			MessageBox(hwnd, rstring(IDS_T_PGP_KEY_OPEN_ERR), 
				NULL, MB_ICONEXCLAMATION | MB_OK); 
			return FALSE; 
		} else { 
            UINT j, k, l = _lread(fp, d->otp, BUFL); 
            if (l == 0) { 
                /* Idiot supplied void key file.  Give 'im 
                   what he asked for: no encryption. */ 
                d->otp[0] = 0; 
                l = 1; 
            } 
            /* If the file is shorter than the maximum buffer 
               we may need to encrypt, replicate the key until 
               the buffer is filled. */ 
            j = l; 
            k = 0; 
            while (j < BUFL) { 
                d->otp[j++] = d->otp[k++]; 
                if (k >= l) { 
                    k = 0; 
                } 
            } 
			_lclose(fp); 
		} 
	} 
#endif 
 
	/* When the keys change, we want to immediately send an 
	   RTP/VAT SDES/ID message in the new encryption so the 
	   other end can sense the protocol and encryption. */ 
	    
	d->sendSDEStimer = 0;	 
	return TRUE;  
} 
 
//	CP_PROC  --  Connection properties dialogue procedure 
 
static LPCLIENT_DATA clientData; 
 
BOOL CALLBACK CP_proc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) 
{ 
	LPCLIENT_DATA d = clientData; 
 
    switch (message) { 
        case WM_INITDIALOG: 
        	{ 
        		char tbuf[132]; 
        		 
        		//	Display host name in dialogue title 
 
#ifdef MODEM        		 
        		if (d->inetSock.sin_addr.s_addr == 0) { 
        			strcpy(tbuf, rstring(IDS_T_MODEM_SP)); 
        			GetWindowText(hDlg, tbuf + strlen(tbuf), (sizeof tbuf) - strlen(tbuf)); 
        		} else 
#endif        		  
        		{ 
	        		GetWindowText(hDlg, tbuf, sizeof tbuf); 
	        		_fstrcat(tbuf, " - "); 
	        		_fstrcat(tbuf, d->szHost); 
	        	} 
        		SetWindowText(hDlg, tbuf); 
				CheckDlgButton(hDlg, IDC_DEBUG, d->debugging); 
				CheckDlgButton(hDlg, IDC_LOOPBACK, d->loopback); 
				SetDlgItemText(hDlg, IDC_CP_DESKEY, d->desKeyString); 
				SetDlgItemText(hDlg, IDC_CP_IDEAKEY, d->ideaKeyString); 
				SetDlgItemText(hDlg, IDC_CP_BLOWFISHKEY, d->blowfishKeyString); 
				SetDlgItemText(hDlg, IDC_CP_OTPFILE, d->otpFileName); 
				SetDlgItemText(hDlg, IDC_CP_PGPUSERS, d->opgpUserList); 
				CheckDlgButton(hDlg, IDC_SAVE_KEYS, d->saveKeys); 
#define Crypple(x)	ShowWindow(GetDlgItem(hDlg, x), SW_HIDE) 
#ifdef CRYPTO 
				Crypple(IDC_CP_NOCRYPTO1); 
				Crypple(IDC_CP_NOCRYPTO2); 
				Crypple(IDC_CP_NOCRYPTO3); 
#define SFonly(x) EnableWindow(GetDlgItem(hDlg, x), protocolSent == PROTOCOL_SPEAKFREE) 
				SFonly(IDC_CP_IDEA); 
				SFonly(IDC_CP_IDEAKEY); 
				SFonly(IDC_CP_BLOWFISH); 
				SFonly(IDC_CP_BLOWFISHKEY); 
				SFonly(IDC_CP_KEYFILE); 
				SFonly(IDC_CP_OTPFILE); 
				SFonly(IDC_CP_PGP); 
				SFonly(IDC_CP_PGPUSERS); 
				SFonly(IDC_CP_PATENT); 
				SFonly(IDC_OTP_BROWSE); 
#undef SFonly				 
#else 
				Crypple(IDC_CP_DES); 
				Crypple(IDC_CP_DESKEY); 
				Crypple(IDC_CP_IDEA); 
				Crypple(IDC_CP_IDEAKEY); 
				Crypple(IDC_CP_BLOWFISH); 
				Crypple(IDC_CP_BLOWFISHKEY); 
				Crypple(IDC_CP_KEYFILE); 
				Crypple(IDC_CP_OTPFILE); 
				Crypple(IDC_CP_PGP); 
				Crypple(IDC_CP_PGPUSERS); 
				Crypple(IDC_CP_PATENT); 
				Crypple(IDC_SAVE_KEYS); 
				Crypple(IDC_OTP_BROWSE); 
#endif 
#undef Crypple 
#ifdef IP_MAX_MEMBERSHIPS 
				EnableWindow(GetDlgItem(hDlg, IDC_CP_MULTI_SCOPE), 
					IN_MULTICAST(d->inetSock.sin_addr.s_addr)); 
				EnableWindow(GetDlgItem(hDlg, IDC_CP_MULTI_LABEL), 
					IN_MULTICAST(d->inetSock.sin_addr.s_addr)); 
				if (IN_MULTICAST(d->inetSock.sin_addr.s_addr)) { 
					SetDlgItemInt(hDlg, IDC_CP_MULTI_SCOPE, d->multicast_scope, FALSE); 
				} 
#else 
				EnableWindow(GetDlgItem(hDlg, IDC_CP_MULTI_SCOPE), FALSE); 
				EnableWindow(GetDlgItem(hDlg, IDC_CP_MULTI_LABEL), FALSE); 
#endif					 
			} 
            break; 
 
        case WM_COMMAND: 
            switch ((short) WM_COMMAND_ID(wParam)) { 
                case IDOK: 
#ifdef IP_MAX_MEMBERSHIPS                 
                	if (GetDlgItemInt(hDlg, IDC_CP_MULTI_SCOPE, NULL, FALSE) > 255) { 
                		MessageBox(hDlg, rstring(IDS_T_MULTICAST_SCOPE_ERR), 
                			NULL, MB_ICONEXCLAMATION | MB_OK); 
                		return TRUE; 
                	} 
#endif                	 
                	d->debugging = IsDlgButtonChecked(hDlg, IDC_DEBUG); 
                	d->loopback = IsDlgButtonChecked(hDlg, IDC_LOOPBACK); 
					GetDlgItemText(hDlg, IDC_CP_DESKEY, d->desKeyString, sizeof d->desKeyString); 
					GetDlgItemText(hDlg, IDC_CP_IDEAKEY, d->ideaKeyString, sizeof d->ideaKeyString); 
					GetDlgItemText(hDlg, IDC_CP_BLOWFISHKEY, d->blowfishKeyString, sizeof d->blowfishKeyString); 
					GetDlgItemText(hDlg, IDC_CP_OTPFILE, d->otpFileName, sizeof d->otpFileName); 
					GetDlgItemText(hDlg, IDC_CP_PGPUSERS, d->opgpUserList, sizeof d->opgpUserList); 
					d->multicast_scope = GetDlgItemInt(hDlg, IDC_CP_MULTI_SCOPE, NULL, FALSE); 
                	d->saveKeys = IsDlgButtonChecked(hDlg, IDC_SAVE_KEYS); 
                	if (!makeInternalEncryptionKeys(GetParent(hDlg), d)) { 
                		break; 
                	} 
	                EndDialog(hDlg, TRUE); 
                    break; 
 
                case IDCANCEL: 
                    EndDialog(hDlg, FALSE); 
                    break; 
 
#ifdef CRYPTO                     
                case IDC_OTP_BROWSE: 
			     	{ 
			     		OPENFILENAME ofn; 
			     		char szString[MAX_PATH]; 
			 
			            memset(&ofn, 0, sizeof(ofn)); 
						ofn.lStructSize = sizeof(OPENFILENAME); 
						ofn.hwndOwner = hDlg; 
						ofn.lpstrFilter = rfilter(IDS_T_KEY_FILE_FILTER); 
						ofn.lpstrCustomFilter = NULL; 
						strcpy(szString, ""); 
						ofn.lpstrFile = (LPSTR) szString; 
						ofn.nMaxFile = sizeof(szString); 
						ofn.lpstrInitialDir = NULL; 
						ofn.lpstrTitle = rstring(IDS_T_OPEN_KEY_FILE_TITLE); 
						ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_SHOWHELP; 
						fileHelpKey = rstring(IDS_HELP_KEY_FILE); 
						if (GetOpenFileName((LPOPENFILENAME) &ofn)) { 
							SetDlgItemText(hDlg, IDC_CP_OTPFILE, szString); 
							_fstrcpy(d->otpFileName, szString); 
						} 
					} 
					break; 
#endif					 
		        	 
                case ID_HELP: 
                	WinHelp(hwndMDIFrame, rstring(IDS_HELPFILE), HELP_KEY, 
                				((DWORD) (Lrstring(IDS_HELP_CONNPROP)))); 
                	holped = TRUE; 
                	break; 
 
                default: 
                    break; 
            } 
            break; 
        	 
        default: 
        	if (message == fileOpenHelpButton && fileHelpKey != NULL) { 
            	WinHelp(hwndMDIFrame, rstring(IDS_HELPFILE), HELP_KEY, 
            				((DWORD) (LPSTR) fileHelpKey)); 
            	holped = TRUE; 
        	} 
        	break;	    	 
    } 
    return FALSE; 
} 
 
//	CONNECTIONPROPERTIES  --  Set properties for an open connection 
 
VOID connectionProperties(HWND hwnd, LPCLIENT_DATA d) 
{ 
    clientData = d; 
    DialogBox(hInst, MAKEINTRESOURCE(IDD_CONNECTION_PROPERTIES), hwnd, CP_proc); 
    return; 
} 
 
//	GENKEYDLGPROC  --  Session key generator dialogue procedure 
 
BOOL CALLBACK genKeyDlgProc(HWND hwnd, UINT nMessage, WPARAM wParam, LPARAM lParam) 
{ 
    switch (nMessage) { 
        case WM_INITDIALOG: 
        	{ 
#ifdef CRYPTO        		 
        		char key[256]; 
 
        		sessionKeyGenerate(key, FALSE); 
				SetDlgItemText(hwnd, IDE_KEY, key); 
#endif				 
			} 
			break; 
				 
        case WM_COMMAND: 
        	switch ((short) WM_COMMAND_ID(wParam)) { 
        	 
		    	case IDOK: 
		        EndDialog(hwnd, TRUE); 
		        break; 
 
#ifdef CRYPTO		         
		    	case IDC_NEW_KEY: 
			    	{ 
		        		char key[256]; 
		        		 
		        		sessionKeyGenerate(key, FALSE); 
						SetDlgItemText(hwnd, IDE_KEY, key); 
						SendMessage(GetDlgItem(hwnd, IDE_KEY), EM_SETSEL, 0, 
							_fstrlen(key) + 1); 
						SetFocus(GetDlgItem(hwnd, IDE_KEY)); 
					} 
					break; 
#endif					 
		        	 
                case ID_HELP: 
                	WinHelp(hwndMDIFrame, rstring(IDS_HELPFILE), HELP_KEY, 
                				((DWORD) (Lrstring(IDS_HELP_KEYGEN)))); 
                	holped = TRUE; 
                	break; 
			} 
    } 
    return FALSE; 
} 
 
//	GENKEYDIALOGUE  --  Generate session key dialogue 
 
VOID genKeyDialogue(HWND hwnd) 
{ 
    DialogBox(hInst, MAKEINTRESOURCE(IDD_GEN_KEY), hwnd, genKeyDlgProc); 
} 
 
//	RANT1_DLGPROC  --  First serial I/O rant dialogue procedure 
 
BOOL CALLBACK rant1_DlgProc(HWND hwnd, UINT nMessage, WPARAM wParam, LPARAM lParam) 
{ 
#ifdef MODEM 
    switch (nMessage) { 
        case WM_COMMAND: 
		    if (WM_COMMAND_ID(wParam) == IDOK) { 
		        EndDialog(hwnd, TRUE); 
		    } else if (WM_COMMAND_ID(wParam) == IDCANCEL) { 
		        EndDialog(hwnd, FALSE); 
		    } 
        	break; 
    } 
#endif     
    return FALSE; 
} 
 
//	RANT1DIALOGUE  --  First serial I/O rant dialogue 
 
int rant1Dialogue(HWND hwndParent) 
{ 
    int result; 
 
    result = DialogBox(hInst, MAKEINTRESOURCE(IDD_MODEM_RANT), hwndParent, rant1_DlgProc); 
    return result; 
} 
 
//	RANT2_DLGPROC  --  Second serial I/O rant dialogue procedure 
 
BOOL CALLBACK rant2_DlgProc(HWND hwnd, UINT nMessage, WPARAM wParam, LPARAM lParam) 
{ 
#ifdef MODEM 
    switch (nMessage) { 
        case WM_INITDIALOG: 
        	CheckDlgButton(hwnd, IDC_RANT, modemShowRant); 
        	break; 
         
        case WM_COMMAND: 
		    if (WM_COMMAND_ID(wParam) == IDOK) { 
		    	modemShowRant = IsDlgButtonChecked(hwnd, IDC_RANT); 
		        EndDialog(hwnd, TRUE); 
		    } else if (WM_COMMAND_ID(wParam) == IDCANCEL) { 
		        EndDialog(hwnd, FALSE); 
		    } 
        	break; 
    } 
#endif     
    return FALSE; 
} 
 
//	RANT2DIALOGUE  --  Second serial I/O rant dialogue 
 
int rant2Dialogue(HWND hwndParent) 
{ 
    int result; 
 
    result = DialogBox(hInst, MAKEINTRESOURCE(IDD_MODEM_RANT_2), hwndParent, rant2_DlgProc); 
    return result; 
} 
 
//	MODEMDLGPROC  --  Modem setup dialogue procedure 
 
BOOL CALLBACK modemDlgProc(HWND hwnd, UINT nMessage, WPARAM wParam, LPARAM lParam) 
{ 
#ifdef MODEM 
#ifndef CBR_28800 
#define CBR_28800	0xFF1A 			// Missing in 3.1 windows.h 
#endif 
	static WORD baudRates[] = { CBR_9600, CBR_14400, CBR_19200, CBR_28800, 
								CBR_38400, CBR_56000, CBR_128000, 
 								CBR_256000 }; 
 	static char *baudNames[] = { "9600", "14400", "19200", "28800", "38400", 
 								 "56000", "128000", "256000", NULL }; 
    switch (nMessage) { 
        case WM_INITDIALOG: 
        	{ 
        		WORD i, n; 
        		HWND ctl = GetDlgItem(hwnd, IDD_MODEM_BAUD_RATE); 
				WORD ncom = LOWORD(EscapeCommFunction(NULL, GETMAXCOM)) + 1; 
        		 
        		CheckDlgButton(hwnd, IDC_MODEM_ENABLE, modemEnable); 
				SetDlgItemText(hwnd, IDC_MODEM_INIT_STRING, modemInitString); 
 
        		for (i = 0; baudNames[i] != NULL; i++) { 
					n = LOWORD(SendMessage(ctl, CB_ADDSTRING, NULL, 
					                       (LPARAM) (LPSTR) baudNames[i])); 
					SendMessage(ctl, CB_SETITEMDATA, (WPARAM) n, 
									(LPARAM) (LONG) baudRates[i]); 
								 
					if (strcmp(baudNames[i], baudrate) == 0) { 
						SendMessage(ctl, CB_SETCURSEL, (WPARAM) n, NULL); 
					} 
        		} 
        		 
        		ctl = GetDlgItem(hwnd, IDD_MODEM_PORT); 
        		for (i = 0; i < ncom; i++) { 
					char comn[12]; 
					 
					wsprintf(comn, Format(32), i + 1); 
					n = LOWORD(SendMessage(ctl, CB_ADDSTRING, NULL, 
					                               (LPARAM) (LPSTR) comn)); 
					SendMessage(ctl, CB_SETITEMDATA, (WPARAM) n, 
					           (LPARAM) (LONG) i + 1); 
								 
					if (_fstrcmp(comn, commport) == 0) { 
						SendMessage(ctl, CB_SETCURSEL, (WPARAM) n, NULL); 
					} 
        		} 
			} 
			break; 
				 
        case WM_COMMAND: 
		    switch ((short) WM_COMMAND_ID(wParam)) { 
		    	case IDOK: 
		    		{ 
				    	DWORD i; 
				    	 
				    	closeModem(hwnd); 
		                modemEnable = IsDlgButtonChecked(hwnd, IDC_MODEM_ENABLE); 
		                GetDlgItemText(hwnd, IDC_MODEM_INIT_STRING, 
		                				modemInitString, sizeof modemInitString); 
		                				 
		                i = SendDlgItemMessage(hwnd, IDD_MODEM_BAUD_RATE, 
		                		CB_GETCURSEL, 0, 0); 
		                if (i != CB_ERR) { 
		                	SendDlgItemMessage(hwnd, IDD_MODEM_BAUD_RATE, CB_GETLBTEXT, 
		                		(WPARAM) i, (LPARAM) (LPCSTR) baudrate);	 
		                } 
		                  
		                i = SendDlgItemMessage(hwnd, IDD_MODEM_PORT, 
		                		CB_GETCURSEL, 0, 0); 
		                if (i != CB_ERR) { 
		                	SendDlgItemMessage(hwnd, IDD_MODEM_PORT, CB_GETLBTEXT, 
		                		(WPARAM) i, (LPARAM) (LPCSTR) commport);	 
		                } 
		                if (modemEnable) { 
					    	if (!openModem(hwnd)) { 
					    		modemEnable = FALSE; 
					    	} 
		                }  
				        EndDialog(hwnd, TRUE); 
				    } 
				    break; 
				     
		    	case IDCANCEL: 
				    EndDialog(hwnd, FALSE); 
				    break; 
				 
				case IDC_MODEM_ENABLE: 
					if (modemShowRant && ((WORD) 
							SendMessage(GetDlgItem(hwnd, IDC_MODEM_ENABLE), 
	    						BM_GETCHECK, 0, 0L))) { 
	    				if (rant1Dialogue(hwnd)) { 
	    					if (rant2Dialogue(hwnd)) { 
	    						break; 
	    					} else { 
	    						CheckDlgButton(hwnd, IDC_MODEM_ENABLE, FALSE); 
	    					} 
	    				} else { 
	    					CheckDlgButton(hwnd, IDC_MODEM_ENABLE, FALSE); 
	    				} 
	    			} 
					break; 
					     
                case ID_HELP: 
                	WinHelp(hwndMDIFrame, rstring(IDS_HELPFILE), HELP_KEY, 
                				((DWORD) (Lrstring(IDS_HELP_MODEM_CONFIG)))); 
                	holped = TRUE; 
                	break; 
		    } 
    } 
#endif     
    return FALSE; 
} 
 
//	MODEMRANT  --  Display rant about lousy serial I/O support on Windows 
 
void modemRant(HWND hwnd) 
{ 
#ifdef MODEM 
	if (rant1Dialogue(hwnd)) { 
		rant2Dialogue(hwnd); 
	} 
#endif	 
} 
 
//	MODEMSETUPDIALOGUE  --  Modem setup dialogue 
 
VOID modemSetupDialogue(HWND hwnd) 
{ 
    DialogBox(hInst, MAKEINTRESOURCE(IDD_MODEM_SETTINGS), hwnd, modemDlgProc); 
} 
 
//	MULTICASTDLGPROC  --  Multicast group membership dialogue procedure 
 
BOOL CALLBACK multicastDlgProc(HWND hwnd, UINT nMessage, WPARAM wParam, LPARAM lParam) 
{ 
#ifdef IP_MAX_MEMBERSHIPS 
    switch (nMessage) { 
        case WM_INITDIALOG: 
        	{ 
        		int i; 
        		HWND ctl = GetDlgItem(hwnd, IDC_MC_GROUPS); 
        	 
        		for (i = 0; i < multiMemberships; i++) { 
        			char mcline[MAX_HOST + 24]; 
        			 
        			if (multiName[i] == NULL) { 
        				_fstrcpy(mcline, inet_ntoa(multiAddr[i]));  
        			} else { 
        				wsprintf(mcline, Format(33), multiName[i], 
        					(LPSTR) inet_ntoa(multiAddr[i])); 
        			} 
					SendMessage(ctl, LB_ADDSTRING, 0, 
						(LPARAM) (LPSTR) mcline); 
        		} 
        		SendMessage(ctl, LB_SETCURSEL, multiMemberships > 0 ? 0 : -1, 0L); 
        		CheckDlgButton(hwnd, IDC_MC_LOOP, multiLoop); 
        		EnableWindow(GetDlgItem(hwnd, IDC_MC_LOOP), !multiBrainDead); 
        		EnableWindow(GetDlgItem(hwnd, IDC_MC_LEAVE), multiMemberships > 0); 
        		EnableWindow(GetDlgItem(hwnd, IDC_MC_JOIN), FALSE); 
			} 
			break; 
				 
        case WM_COMMAND: 
		    switch ((short) WM_COMMAND_ID(wParam)) { 
		    	case IDOK: 
		    		{ 
		    			int i, n; 
		    			 
		    			multicastJoin(hwnd, FALSE);	// Drop current groups 
		    			multiLoop = IsDlgButtonChecked(hwnd, IDC_MC_LOOP); 
		    			n = (int) SendDlgItemMessage(hwnd, IDC_MC_GROUPS, LB_GETCOUNT, 0, 0L); 
		    			for (i = 0; i < n; i++) { 
		    				char s[MAX_HOST + 24]; 
		    				char *cp; 
		    				 
		    				SendDlgItemMessage(hwnd, IDC_MC_GROUPS, LB_GETTEXT, i, 
		    					(LPARAM) (LPCSTR) s); 
		    				if ((cp = strchr(s, '(')) != NULL) { 
		    					char *cp1; 
		    					 
		    					cp++; 
		    					cp1 = strchr(cp, ')'); 
		    					if (cp1 != NULL) { 
		    						*cp1 = 0; 
		    					} 
		    				} else { 
		    					cp = s; 
		    				} 
		    				multiAddr[i].s_addr = inet_addr(cp); 
		    				multiName[i] = NULL; 
		    				if (cp > s) { 
		    					LPSTR np; 
		    					 
		    					cp[-2] = 0; 
		    					np = GlobalAllocPtr(GPTR, strlen(s) + 1); 
		    					if (np != NULL) { 
		    						_fstrcpy(np, s); 
		    						multiName[i] = np; 
		    					} 
		    				} 
		    			} 
		    			multiMemberships = n; 
		    			multicastJoin(hwnd, TRUE);		// Join newly chosen groups 
		    		} 
				    EndDialog(hwnd, TRUE); 
				    break; 
				     
		    	case IDCANCEL: 
				    EndDialog(hwnd, FALSE); 
				    break; 
				     
				case IDC_MC_NEW_GROUP: 
					if (WM_COMMAND_NOTIFY == EN_CHANGE) { 
						EnableWindow(GetDlgItem(hwnd, IDC_MC_JOIN), 
							(multiMemberships < IP_MAX_MEMBERSHIPS) && 
							(SendDlgItemMessage(hwnd, IDC_MC_NEW_GROUP, EM_LINELENGTH, 0, 0L) > 0)); 
					} 
					break; 
				     
				case IDC_MC_JOIN: 
					{ 
						char group[MAX_HOST]; 
						int l; 
						struct in_addr newaddr; 
						 
						*((WORD *) group) = sizeof group; 
						l = (int) SendDlgItemMessage(hwnd, IDC_MC_NEW_GROUP, EM_GETLINE, 
							0, (LPARAM) (LPSTR) group); 
						group[l] = 0; 
						newaddr.s_addr = inet_addr(group); 
						if (newaddr.s_addr == INADDR_NONE) { 
							LPHOSTENT h = gethostbyname(group); 
							 
							if (h == NULL) { 
					            int serr = WSAGetLastError(); 
						             
						        MsgBox(hwnd, MB_ICONSTOP | MB_OK, Format(39), 
						                (LPSTR) group, 
						                serr, SockerrToString(serr)); 
						        group[0] = 0; 
							} else { 
								newaddr = *((LPIN_ADDR) h->h_addr);  
								wsprintf(group + strlen(group), Format(34), 
									(LPSTR) inet_ntoa(newaddr)); 
							} 
						} 
						if (group[0] != 0 && !IN_MULTICAST(newaddr.s_addr)) { 
					        MsgBox(hwnd, MB_ICONSTOP | MB_OK, Format(35), 
					                ((LPSTR) inet_ntoa(newaddr))); 
					        group[0] = 0; 
						} 
						if (group[0] != 0) { 
							int nitem, ic; 
								 
							//	Clear input field 
							SetDlgItemText(hwnd, IDC_MC_NEW_GROUP, "");  
							 
							//	Make sure it's not already in the box 
							nitem = (int) SendDlgItemMessage(hwnd, IDC_MC_GROUPS, LB_FINDSTRINGEXACT, 
									(WPARAM) -1, (LPARAM) (LPCSTR) group);  
							if (nitem == LB_ERR) { 
								nitem = (int) SendDlgItemMessage(hwnd, IDC_MC_GROUPS, LB_ADDSTRING, 0, 
									(LPARAM) (LPCSTR) group); 
								ic = (int) SendDlgItemMessage(hwnd, IDC_MC_GROUPS, LB_GETCOUNT, 0, 0L); 
        						EnableWindow(GetDlgItem(hwnd, IDC_MC_LEAVE), ic > 0); 
								EnableWindow(GetDlgItem(hwnd, IDC_MC_JOIN), FALSE); 
							} 
							if (nitem != LB_ERR) { 
								SendDlgItemMessage(hwnd, IDC_MC_GROUPS, LB_SETCURSEL, nitem, 0L); 
							} 
						} 
				        //	Set focus back to the edit field 
				        SetFocus(GetDlgItem(hwnd, IDC_MC_NEW_GROUP)); 
					} 
					break; 
				     
				case IDC_MC_LEAVE: 
					{ 
						int item = (int) SendDlgItemMessage(hwnd, IDC_MC_GROUPS, 
											LB_GETCURSEL, 0, 0L); 
						if (item != LB_ERR) { 
							int itemc; 
							 
							SendDlgItemMessage(hwnd, IDC_MC_GROUPS, LB_DELETESTRING, item, 0L); 
							itemc = (int) SendDlgItemMessage(hwnd, IDC_MC_GROUPS, LB_GETCOUNT, 0, 0L); 
    						EnableWindow(GetDlgItem(hwnd, IDC_MC_LEAVE), itemc > 0); 
							EnableWindow(GetDlgItem(hwnd, IDC_MC_JOIN), 
								(itemc < IP_MAX_MEMBERSHIPS) && 
								(SendDlgItemMessage(hwnd, IDC_MC_NEW_GROUP, EM_LINELENGTH, 0, 0L) > 0)); 
        					SendDlgItemMessage(hwnd, IDC_MC_GROUPS, 
        						LB_SETCURSEL, item >= itemc ? itemc - 1 : item, 0L); 
						}  
					} 
					break; 
					 
                case ID_HELP: 
                	WinHelp(hwndMDIFrame, rstring(IDS_HELPFILE), HELP_KEY, 
                				((DWORD) (Lrstring(IDS_HELP_MULTICAST)))); 
                	holped = TRUE; 
                	break; 
		    } 
    } 
#endif     
    return FALSE; 
} 
 
//	MULTICASTGROUPSDIALOGUE  --  Multicast group membership dialogue 
 
VOID multicastGroupsDialogue(HWND hwnd) 
{ 
    DialogBox(hInst, MAKEINTRESOURCE(IDD_MULTICAST), hwnd, multicastDlgProc); 
} 
 
 
//	ABOUT_DLGPROC  --  About dialogue procedure 
 
BOOL CALLBACK About_DlgProc(HWND hwnd, UINT nMessage, WPARAM wParam, LPARAM lParam) 
{ 
    switch (nMessage) { 
    	case WM_INITDIALOG: 
    	{ 
    		char s[80]; 
	      int					    iRc; 
	      LPHOSTENT		    lphp; 
	      struct in_addr	in_addrIP; 
    		 
     	wsprintf(s, Format(75), 8 * sizeof(int)); 
    	SetDlgItemText(hwnd, IDC_ABOUT_TITLE, s); 
				  
   		if (aboutInSamples != 0) { 
    			_fstrcpy(s, inputActive ? rstring(IDS_T_ACTIVE) : rstring(IDS_T_IDLE)); 
    			wsprintf(s + strlen(s), Format(50), 
    				aboutInSamples, aboutInBits); 
    			SetDlgItemText(hwnd, IDC_ABOUT_INPUT, s);  
    		} else { 
    			SetDlgItemText(hwnd, IDC_ABOUT_INPUT, rstring(IDS_T_NEVER_USED)); 
    		} 
 
    		if (aboutOutSamples != 0) { 
    			_fstrcpy(s, outputActive ? rstring(IDS_T_ACTIVE) : rstring(IDS_T_IDLE)); 
    			wsprintf(s + strlen(s), Format(50), 
    				aboutOutSamples, aboutOutBits); 
    			SetDlgItemText(hwnd, IDC_ABOUT_OUTPUT, s);  
    		} else { 
    			SetDlgItemText(hwnd, IDC_ABOUT_OUTPUT, rstring(IDS_T_NEVER_USED)); 
    		} 
    		 
    		ShowWindow(GetDlgItem(hwnd, IDC_ABOUT_DUPLEX), 
    			halfDuplex ? SW_SHOW : SW_HIDE); 
#ifdef CRYPTO 
    		ShowWindow(GetDlgItem(hwnd, IDC_ABOUT_CRYPTO_ON), SW_SHOW); 
    		ShowWindow(GetDlgItem(hwnd, IDC_ABOUT_CRYPTO_OFF), SW_HIDE); 
#else 
    		ShowWindow(GetDlgItem(hwnd, IDC_ABOUT_CRYPTO_OFF), SW_SHOW); 
    		ShowWindow(GetDlgItem(hwnd, IDC_ABOUT_CRYPTO_ON), SW_HIDE); 
    		GetDlgItemText(hwnd, IDC_ABOUT_VERSION, s, sizeof s); 
    		_fstrcat(s, " (No Crypto)"); 
    		SetDlgItemText(hwnd, IDC_ABOUT_VERSION, s); 
#endif 
 
        // Display local IP address. 
			  iRc = gethostname(s, 80); 
        lphp = NULL; 
 
			  if (iRc != SOCKET_ERROR) 
        { 
			    lphp = gethostbyname(s); 
			  } 
 
        if(lphp != NULL) 
        { 
			    in_addrIP = *(struct in_addr far *)(lphp->h_addr); 
          wsprintf(s, "%s", (LPSTR)inet_ntoa(in_addrIP)); 
        } 
        else 
        { 
          strcpy(s, "Unknown"); 
        } 
    	   
        SetDlgItemText(hwnd, IDC_ABOUT_IP_ADDRESS, s); 
 
        sprintf(s, "$%.2f", fTotalMoneySaved); 
        SetDlgItemText(hwnd, IDC_ABOUT_MONEY_SAVED, s); 
    	} 
    	break; 
 
     
        case WM_COMMAND: 
        	switch ((short) WM_COMMAND_ID(wParam)) { 
        	 
		    	case IDOK: 
		        	EndDialog(hwnd, TRUE); 
		        	break; 
		        	 
                case ID_HELP: 
                	WinHelp(hwndMDIFrame, rstring(IDS_HELPFILE), HELP_KEY, 
                				((DWORD) (Lrstring(IDS_HELP_ABOUT)))); 
                	holped = TRUE; 
                	break;		        	 
		    } 
        	break; 
    } 
    return FALSE; 
} 
 
//	ABOUTDIALOGUE  --  About dialogue 
 
VOID aboutDialogue(HWND hwndParent) 
{ 
    DialogBox(hInst, IDD_ABOUT, hwndParent, About_DlgProc); 
} 
 
/*	PROPUPDATEAUDIO  --  Update audio configuration information in the 
						 propeller head panel.  */ 
						  
void propUpdateAudio(void) 
{ 
	if (hDlgPropeller != NULL) { 
		char s[80]; 
		 
		if (aboutInSamples != 0) { 
			_fstrcpy(s, inputActive ? rstring(IDS_T_ACTIVE_COMMA) : rstring(IDS_T_IDLE_COMMA)); 
			wsprintf(s + strlen(s), Format(36), 
				aboutInBits, aboutInSamples); 
			SetDlgItemText(hDlgPropeller, IDC_PH_AUDIO_IN, s);  
		} else { 
			SetDlgItemText(hDlgPropeller, IDC_PH_AUDIO_IN, rstring(IDS_T_NONE)); 
		} 
		 
		if (aboutOutSamples != 0) { 
			_fstrcpy(s, outputInShutdown ? rstring(IDS_T_TERMINATING_COMMA) : 
				(halfDuplexTransition ? rstring(IDS_T_TRANSITION_COMMA) :  
				(outputActive ? rstring(IDS_T_ACTIVE_COMMA) : rstring(IDS_T_IDLE_COMMA)))); 
			wsprintf(s + strlen(s), Format(36), 
				aboutOutBits, aboutOutSamples); 
			SetDlgItemText(hDlgPropeller, IDC_PH_AUDIO_OUT, s); 
			if (outputPending == 0) { 
				wsprintf(s, Format(6)); 
			} else { 
				wsprintf(s, Format(7), outputPending); 
			} 
			SetDlgItemText(hDlgPropeller, IDC_PH_AUDIO_OUT_QUEUE, s); 
		} else { 
			SetDlgItemText(hDlgPropeller, IDC_PH_AUDIO_OUT, rstring(IDS_T_NONE)); 
		} 
		 
		SetDlgItemText(hDlgPropeller, IDC_PH_AUDIO_DUPLEX, 
			halfDuplex ? rstring(IDS_T_HALF_DUPLEX) : rstring(IDS_T_FULL_DUPLEX)); 
			 
		SetDlgItemInt(hDlgPropeller, IDC_PH_CONNECTIONS, openConnections, FALSE); 
		SetDlgItemInt(hDlgPropeller, IDC_PH_PACKET_SENDSIZE, inputSampleCount(), FALSE); 
 
		SetDlgItemText(hDlgPropeller, IDC_PH_COMPRESSION, 
							rstring(IDS_COMPRESSION_TYPES + ((compression ? 1 : 0) | 
										 ((gsmcompress || voxcompress) ? 2 : 0) | 
										 (adpcmcompress ? 4 : 0) | 
										 (lpccompress ? 8 : 0) | 
										 (lpc10compress ? 16 : 0)))); 
	} 
}						  
 
//	PROPELLERHEADDLGPROC  --  Propeller head dialogue procedure 
 
BOOL CALLBACK propellerHeadDlgProc(HWND hwnd, UINT nMessage, WPARAM wParam, LPARAM lParam) 
{ 
    switch (nMessage) { 
    	case WM_INITDIALOG: 
	    	{ 
	    		char s[80]; 
	    		 
	    		if (aboutUDPmax != 0) { 
	    			wsprintf(s, Format(37), aboutUDPmax); 
	    			SetDlgItemText(hwnd, IDC_PH_PACKET_SIZE, s);  
	    		} 
#define Prop(item, value) wsprintf(s, Format(0), value); SetDlgItemText(hwnd, item, s) 	    		 
	    		Prop(IDC_PH_PACKETS_RECEIVED, packetsReceived); 
	    		Prop(IDC_PH_PACKETS_SENT, packetsSent); 
	    		Prop(IDC_PH_INPUT_LOST, inputPacketsLost); 
	    		Prop(IDC_PH_OUTPUT_LOST, outputPacketsLost); 
	    		Prop(IDC_PH_MESSAGE_QUEUE, (long) messageQueueSize); 
	    		Prop(IDC_PH_MSGCHECK, messageChecks);  
	    		SetDlgItemText(hwnd, IDC_PH_SENDTO, 
	    				useSendNotSendto ? rstring(IDS_T_SEND) : rstring(IDS_T_SENDTO)); 
#undef Prop 
				hDlgPropeller = hwnd; 
				propUpdateAudio();	    		 
	    	} 
	    	return TRUE; 
	    	 
	    case WM_CLOSE: 
	    	DestroyWindow(hwnd); 
	    	return TRUE; 
 
        case WM_COMMAND: 
		    switch ((short) WM_COMMAND_ID(wParam)) { 
		    	case IDOK: 
		        	PostMessage(hwnd, WM_CLOSE, 0, 0L); 
		        	break; 
		        	 
                case ID_HELP: 
                	WinHelp(hwndMDIFrame, rstring(IDS_HELPFILE), HELP_KEY, 
                				((DWORD) (Lrstring(IDS_HELP_PROPELLER)))); 
                	holped = TRUE; 
                	break; 
		    } 
        	return TRUE; 
	    	 
	    case WM_DESTROY: 
	    	hDlgPropeller = NULL; 
	    	return 0; 
    } 
    return FALSE; 
} 
 
//	PROPELLERHEADDIALOGUE  --  Expert status dialogue 
 
VOID propellerHeadDialogue(HWND hwndParent) 
{ 
    hDlgPropeller = CreateDialog(hInst, MAKEINTRESOURCE(IDD_PROPELLER_HEAD), 
    				hwndParent, propellerHeadDlgProc); 
} 
 
/*  NEWHOST_ENABLECONTROLS  --  Enable/disable controls (other 
								than the Cancel button) in the New 
								Host dialogue.  */ 
 
static VOID NewHost_EnableControls(HWND hwnd, BOOL fEnable) 
{ 
    EnableWindow(GetDlgItem(hwnd, IDD_NEW_HOST), fEnable); 
    EnableWindow(GetDlgItem(hwnd, IDD_NEW_HOST_NAME), fEnable); 
    EnableWindow(GetDlgItem(hwnd, IDOK), fEnable); 
 
    /*  If we enabling the dialog controls, it is due to a 
        failure to retrieve the host data, so set the focus 
        to the host edit field.  If we're disabling the controls, 
        set the focus to the cancel button since that's the only 
        thing we haven't disabled. */ 
 
    SetFocus(GetDlgItem(hwnd, fEnable ? IDD_NEW_HOST : IDCANCEL)); 
} 
 
/*	NEWHOST_ONSOCKETASYNC  --  Handles reply from lookup of host 
							   name or IP address.  */ 
 
static VOID NewHost_OnSocketAsync(HWND hwnd, SOCKERR hAsync, 
                            	  SOCKERR serr, SOCKEVENT cbBuffer) 
{ 
    LPHOSTENT phostent; 
 
    phostent = (LPHOSTENT) NewHostParams.bBuffer; 
 
    if (serr != 0) {  
 
        //  Error retrieving host name/address 
         
        if (NewHostParams.laddr == INADDR_NONE) {  
	        MsgBox(hwnd, MB_ICONSTOP | MB_OK, Format(41), 
	                NewHostParams.pszHostName, serr, SockerrToString(serr)); 
	 
	        //  Reenable the dialog controls 
	 
	        NewHost_EnableControls(hwnd, TRUE); 
	        return; 
	    } else { 
	    	struct in_addr in; 
	    	 
	    	in.s_addr = NewHostParams.laddr;  
	    	_fstrcpy(NewHostParams.pszHostName, inet_ntoa(in)); 
	    	_fmemcpy(NewHostParams.paddr, &NewHostParams.laddr, sizeof(IN_ADDR)); 
    		EndDialog(hwnd, TRUE); 
    		return; 
	    } 
    } 
     
    //  Found the host 
 
    _fstrcpy(NewHostParams.pszHostName, phostent->h_name); 
    _fmemcpy(NewHostParams.paddr, phostent->h_addr, sizeof(IN_ADDR)); 
 
    EndDialog(hwnd, TRUE); 
} 
 
/*  NEWHOST_ONCOMMAND  --  Handle child control messages in the new 
						   host dialogue.  */ 
 
static VOID NewHost_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify) 
{ 
    HANDLE  hAsyncTask; 
    SOCKERR serr; 
 
    //  Interpret the command 
 
    switch (id) { 
     
	    case IDOK: 
	        // handled below 
	        break; 
	 
	    case IDCANCEL: 
	     
	        //  Cancel any pending async operation started by this dialog 
	 
	        if (NewHostParams.hAsync != NULL) { 
	            WSACancelAsyncRequest(NewHostParams.hAsync); 
	            NewHostParams.hAsync = NULL; 
	        } 
	        EndDialog(hwnd, FALSE); 
	        return; 
 
#ifdef MODEM	         
	    case IDC_NEW_MODEM: 
	    	{ 
	    		if ((WORD) SendMessage(GetDlgItem(hwnd, IDC_NEW_MODEM), 
	    				BM_GETCHECK, 0, 0L)) { 
		    		ShowWindow(GetDlgItem(hwnd, IDD_NEW_HOST_NAME), SW_HIDE); 
		    		ShowWindow(GetDlgItem(hwnd, IDD_NEW_HOST_DIAL_STRING), SW_SHOW); 
		    	} else { 
		    		ShowWindow(GetDlgItem(hwnd, IDD_NEW_HOST_NAME), SW_SHOW); 
		    		ShowWindow(GetDlgItem(hwnd, IDD_NEW_HOST_DIAL_STRING), SW_HIDE); 
	    		} 
	    	} 
	    	return; 
#endif	    	 
	    	 
        case ID_HELP: 
        	WinHelp(hwndMDIFrame, rstring(IDS_HELPFILE), HELP_KEY, 
        				((DWORD) (Lrstring(IDS_HELP_NEWCONN)))); 
        	holped = TRUE; 
        	return; 
	 
	    default: 
	        return; 
    } 
 
    /*  We only make it to this point if the command was OK. 
        Get the host name/address from the edit field. */ 
 
    Edit_GetText(GetDlgItem(hwnd, IDD_NEW_HOST), NewHostParams.pszHostName, 
                  MAX_HOST); 
 
#ifdef MODEM 
    if (IsDlgButtonChecked(hwnd, IDC_NEW_MODEM)) { 
    	COMSTAT cs; 
    	 
    	if (modemSessions != 0) { 
			MessageBox(hwnd, rstring(IDS_T_MODEM_BUSY), NULL, MB_ICONEXCLAMATION | MB_OK); 
			return; 
    	} 
    	 
    	//	Send the modem dialing command 
    	 
    	V GetCommError(modemHandle, &cs); 
    	WriteComm(modemHandle, NewHostParams.pszHostName, 
    				_fstrlen(NewHostParams.pszHostName)); 
    	V GetCommError(modemHandle, &cs); 
    	WriteComm(modemHandle, "\r", 1); 
    	V GetCommError(modemHandle, &cs); 
    				  
		//	Zero Internet address indicates modem connection 
		 
    	_fmemset(NewHostParams.paddr, 0, sizeof(IN_ADDR)); 
    	 
    	EndDialog(hwnd, TRUE); 
    } else 
#endif     
    { 
    	LPSTR cp; 
    	unsigned int port = 0; 
     
	    if (NewHostParams.pszHostName[0] == '\0') { 
	        return; 
	    } 
	     
	    /*	If a port address is specified, save it and remove from 
	    	the host name.  */ 
	    	 
	    if ((cp = _fstrchr(NewHostParams.pszHostName, '/')) != NULL || 
	    	(cp = _fstrchr(NewHostParams.pszHostName, ':')) != NULL) { 
	    	char cb[MAX_HOST]; 
	    	 
	    	_fstrcpy(cb, cp + 1); 
	    	port = (unsigned int) atol(cb); 
	    	if (port <= 0) { 
		        MsgBox(hwnd, MB_ICONSTOP | MB_OK, Format(72), *cp);  
		        return; 
	    	} 
	    	*cp = 0; 
	    } else { 
	    	port = NETFONE_COMMAND_PORT; 
	    } 
	    *NewHostParams.port_no = (unsigned short) port; 
	    	 
	    //  Check to see if it is a dotted IP address 
	 
	    NewHostParams.laddr = inet_addr(NewHostParams.pszHostName); 
	 
	    if (NewHostParams.laddr == INADDR_NONE) { 
	 
	        //  Assume the user gave us an actual host name 
	 
	        hAsyncTask = WSAAsyncGetHostByName(hwnd, WM_SOCKET_ASYNC, 
							NewHostParams.pszHostName, NewHostParams.bBuffer, 
							sizeof(NewHostParams.bBuffer)); 
	    } else { 
	 
	        //  The user gave us a dotted IP address 
	         
	        if (!waNetSynchronousGetHostnameAction) { 
		        hAsyncTask = WSAAsyncGetHostByAddr(hwnd, WM_SOCKET_ASYNC, 
		              			(CHAR FAR *) &NewHostParams.laddr, 
		              			sizeof(NewHostParams.laddr), PF_INET, 
		              			NewHostParams.bBuffer, sizeof(NewHostParams.bBuffer)); 
		    } else { 
		    	int serr; 
			    LPHOSTENT h = gethostbyaddr((CHAR FAR *) (CHAR FAR *) &NewHostParams.laddr, 
			                                 sizeof(NewHostParams.laddr), 
			                                 PF_INET); 
		      	serr = (h == NULL) ?  WSAGetLastError() : 0; 
		      	if (h != NULL) { 
		      		_fmemcpy(NewHostParams.bBuffer, h, sizeof(NewHostParams.bBuffer));  
		      	} 
		      	NewHost_OnSocketAsync(hwnd, 0, serr, (SOCKEVENT) 0); 
		      	return; 
	    	} 
	    } 
	 
	    if (hAsyncTask == NULL) { 
	 
	        //  Could not initiate the asynchronous API 
	 
	        serr = WSAGetLastError(); 
	        MsgBox(hwnd, MB_ICONSTOP | MB_OK, Format(40), 
	                NewHostParams.pszHostName, serr, SockerrToString(serr)); 
	        return; 
	    } 
	 
	    /*  The async command has been issued.  Disable all dialog 
	        controls except [Cancel]. */ 
	 
	    NewHost_EnableControls(hwnd, FALSE); 
	} 
} 
 
/*	NEWHOST_DLGPROC  --  New host dialogue procedure.  */ 
 
BOOL CALLBACK NewHost_DlgProc(HWND hwnd, UINT nMessage, WPARAM wParam, 
                               LPARAM lParam) 
{ 
    switch (nMessage) { 
     
    	case WM_INITDIALOG: 
    		Edit_LimitText(GetDlgItem(hwnd, IDD_NEW_HOST), MAX_HOST); 
#ifdef MODEM    		 
    		EnableWindow(GetDlgItem(hwnd, IDC_NEW_MODEM), 
    			modemHandle != -1 && modemSessions == 0); 
#else 
			ShowWindow(GetDlgItem(hwnd, IDC_NEW_MODEM), SW_HIDE);    			 
#endif    			 
    		ShowWindow(GetDlgItem(hwnd, IDD_NEW_HOST_NAME), SW_SHOW); 
    		ShowWindow(GetDlgItem(hwnd, IDD_NEW_HOST_DIAL_STRING), SW_HIDE); 
    		break; 
    		 
    	case WM_COMMAND: 
    		NewHost_OnCommand(hwnd, (short) WM_COMMAND_ID(wParam), (HWND) (UINT) lParam, 
    			(UINT) WM_COMMAND_NOTIFY);   
    		break; 
    		 
    	case WM_SOCKET_ASYNC: 
    		NewHost_OnSocketAsync(hwnd, (SOCKET) (wParam), 
    			(SOCKERR) WSAGETSELECTERROR(lParam), 
    			(SOCKEVENT) WSAGETSELECTEVENT(lParam)); 
    		break; 
    } 
    return FALSE; 
} 
 
/*	NEWHOSTDIALOGUE  --  Open a new connection to a given host name or 
						 IP number.  */ 
 
BOOL newHostDialogue(HWND hwndParent, LPSTR pszHostName, LPIN_ADDR paddr, 
					 unsigned short *port) 
{ 
    BOOL fResult; 
 
    //  Setup dialog parameters 
 
    _fmemset(&NewHostParams, 0, sizeof(NewHostParams)); 
 
    NewHostParams.pszHostName = pszHostName; 
    NewHostParams.paddr = paddr; 
    NewHostParams.hAsync = NULL; 
    NewHostParams.port_no = port; 
	     
    //  Invoke the dialogue 
	 
    fResult = DialogBox(hInst, IDD_NEW, hwndParent, NewHost_DlgProc); 
    return fResult; 
} 
 
//	VOX Monitor dialogue handler 
 
static HWND hDlgVoxMonitor = NULL; 
static long nCurrentAudioLevel = 0; 
static long nCurrentVoxLevel = 0; 
static int PrevNoiseThreshold = 0; 
 
static void PaintLevel(HWND hCtrl, int bPaint) 
{ 
  	HDC hdc; 
  	RECT rect; 
  	HBRUSH hbrush, hbrush2; 
  	int len, NewTop, VoxTop; 
  	double val, scl; 
    static int OldTop = 0; 
    static int OldVox = 0; 
    static int RecLevel = 0; 
    if (RecLevel++ > 0) { 
    	--RecLevel; 
    	return; 
    } 
  	if (bPaint) { 
  		InvalidateRect(hCtrl, NULL, TRUE); 
  		UpdateWindow(hCtrl); 
  	} 
  	hdc = GetDC(hCtrl); 
  	GetClientRect(hCtrl, &rect); 
  	scl = log(32767.0); 
  	 
  	//	Paint the green bar showing the current audio level 
  	 
  	if (nCurrentAudioLevel > 0) { 
      val = log((double) nCurrentAudioLevel); 
    } else { 
      val = 0; 
    } 
  	len = rect.bottom - rect.top; 
  	NewTop = len - (int) ((val * len) / scl); 
  	hbrush = CreateSolidBrush(RGB(0, 255 ,0)); 
  	if (!bPaint) { 
  		if (NewTop > OldTop) { 
  			rect.bottom = NewTop; 
  			rect.top = OldTop; 
	  		FillRect(hdc, &rect, GetStockObject(WHITE_BRUSH)); 
  		} else { 
  			rect.bottom = OldTop; 
  			rect.top = NewTop; 
	  		FillRect(hdc, &rect, hbrush); 
	  	} 
    } else { 
  		FillRect(hdc, &rect, GetStockObject(WHITE_BRUSH)); 
  		rect.top = NewTop; 
  		FillRect(hdc, &rect, hbrush); 
    } 
  	OldTop = NewTop; 
  	 
  	//	Paint the red bar showing the VOX level 
  	 
  	hbrush2 = CreateSolidBrush(RGB(255,0,0)); 
	VoxTop =  1 + (int) (((double) noise_threshold * (len - 1)) / 1000.0); 
	if (!bPaint && (OldVox != VoxTop)) { 
		rect.top = OldVox; 
		rect.bottom = rect.top - 1; 
		if (OldVox > NewTop) { 
			FillRect(hdc, &rect, hbrush); 
		} else { 
	  		FillRect(hdc, &rect, GetStockObject(WHITE_BRUSH)); 
	  	} 
	} 
  	rect.top = VoxTop; 
	rect.bottom = rect.top - 1; 
	FillRect(hdc, &rect, hbrush2); 
	OldVox = VoxTop; 
  	DeleteObject(hbrush2); 
  	DeleteObject(hbrush); 
  	ReleaseDC(hCtrl, hdc); 
    --RecLevel; 
} 
 
static void UpdateScroll(HWND hwnd) 
{ 
	char sNum[16]; 
	double v; 
	 
  	if (PrevNoiseThreshold != noise_threshold) { 
		SetScrollPos(GetDlgItem(hwnd, IDC_VOX_SENSITIVITY), SB_CTL, noise_threshold, TRUE); 
		v = 100.0 - ((double) noise_threshold / 10.0); 
		sprintf(sNum, "%2.2lf", v); 
		SetDlgItemText(hwnd, IDC_VOX_SHOW, sNum); 
  		PrevNoiseThreshold = noise_threshold; 
	} 
} 
 
BOOL CALLBACK voxMonitor_DlgProc(HWND hwnd, UINT nMessage, WPARAM wParam, LPARAM lParam) 
{ 
    switch (nMessage) { 
    	case WM_INITDIALOG: 
	    	{ 
	    		SetScrollRange(GetDlgItem(hwnd, IDC_VOX_SENSITIVITY), SB_CTL, 0, 1000, TRUE); 
	    	  	nCurrentAudioLevel = 0; 
  				PrevNoiseThreshold = noise_threshold - 1; 
	    	  	UpdateScroll(hwnd); 
	    	} 
	    	return TRUE; 
	    	 
	    case WM_CLOSE: 
	    	DestroyWindow(hwnd); 
	    	return TRUE; 
	     
	    case WM_VSCROLL: 
		    switch (wParam) { 
		    	case SB_BOTTOM: 
		    		noise_threshold = 0; 
		    		break; 
		    	case SB_TOP: 
		    		noise_threshold = 1000; 
		    		break; 
		    	case SB_LINEUP: 
		    		noise_threshold -= 10; 
		    		break; 
		    	case SB_LINEDOWN: 
		    		noise_threshold += 10; 
		    		break; 
		    	case SB_PAGEUP: 
		    		noise_threshold -= 100; 
		    		break; 
		    	case SB_PAGEDOWN: 
		    		noise_threshold += 100; 
		    		break; 
		    	case SB_THUMBTRACK: 
		    	case SB_THUMBPOSITION: 
		    		noise_threshold = LOWORD(lParam); 
		    		break; 
		    } 
		    if (noise_threshold < 0) { 
		    	noise_threshold = 0; 
		    } else if (noise_threshold > 1000) { 
		    	noise_threshold = 1000; 
		    } 
	    	UpdateScroll(hwnd); 
	    	if (!inputActive) { 
	    		PaintLevel(GetDlgItem(hwnd, IDC_VOX_LEVEL), 1); 
	    	} 
		    return TRUE; 
 
        case WM_COMMAND: 
		    switch ((short) WM_COMMAND_ID(wParam)) { 
		    	case IDOK: 
		        	PostMessage(hwnd, WM_CLOSE, 0, 0L); 
		        	break; 
		        	 
                case ID_HELP: 
                	WinHelp(hwndMDIFrame, rstring(IDS_HELPFILE), HELP_KEY, 
                				((DWORD) (Lrstring(IDS_HELP_VOX)))); 
                	holped = TRUE; 
                	break; 
		    } 
        	return TRUE; 
         
        case WM_PAINT: 
        	PaintLevel(GetDlgItem(hwnd, IDC_VOX_LEVEL), TRUE); 
        	return FALSE; 
 
	    case WM_DESTROY: 
	    	hDlgVoxMonitor = NULL; 
	    	return FALSE; 
    } 
    return FALSE; 
} 
 
BOOL voxMonitorDialog(HWND hwndParent) 
{ 
    if (hDlgVoxMonitor != NULL) { 
    	return FALSE; 
    } 
    hDlgVoxMonitor = CreateDialog(hInst, MAKEINTRESOURCE(IDD_VOX), hwndParent, voxMonitor_DlgProc); 
    return TRUE; 
} 
 
BOOL IsVoxMonitorMessage(MSG *pmsg) 
{ 
    if (!hDlgVoxMonitor) { 
    	return FALSE; 
    } 
    return IsDialogMessage(hDlgVoxMonitor, pmsg); 
} 
 
void voxMonitorUpdate(long nAudio, long nVox) 
{ 
  	if (!hDlgVoxMonitor) { 
   		return; 
   	} 
  	nCurrentAudioLevel = nAudio; 
  	nCurrentVoxLevel = nVox; 
    PaintLevel(GetDlgItem(hDlgVoxMonitor, IDC_VOX_LEVEL), 0); 
    UpdateScroll(hDlgVoxMonitor); 
} 
 
BOOL IsVoxMonitorOn() 
{ 
    return (hDlgVoxMonitor != NULL); 
} 
 
//	SPLASH_DLGPROC  --  Splash Window procedure 
 
BOOL CALLBACK Splash_DlgProc(HWND hwnd, UINT nMessage, WPARAM wParam, LPARAM lParam) 
{ 
    switch (nMessage) { 
        case WM_COMMAND: 
        	switch ((short) WM_COMMAND_ID(wParam)) { 
        	 
		    	case IDOK: 
		        	EndDialog(hwnd, TRUE); 
		        	break; 
		    } 
        	break; 
    } 
    return FALSE; 
}