home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Network Support Encyclopedia 96-1
/
novell-nsepro-1996-1-cd2.iso
/
download
/
netware
/
chatwn.exe
/
CHAT.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-11-12
|
74KB
|
1,892 lines
/* Brenda Wallace */
/* This program uses the Client SDK for Windows version 1.0 to implement
a chat program. The user can specify either IPX, SPX or TLI as the
comm protocol.
*/
#define WINDOWS 1
#define NWWIN 1
#include <windows.h>
#include <nwcalls.h>
#include <nxtw.h> /* IPX/SPX header */
#include <tispxipx.h> /* TLI - IPX/SPX specific structures */
#include <tiuser.h> /* TLI header */
#include "chat.h"
#include "dos.h"
#define LONG_LIVED 0xFF
#define LISTEN_SOCKET 0x4545
#define CONNECT_SOCKET 0x4646
#define MAX_RECEIVE_ECBS 10
#define MAX_SEND_ECBS 10
#define MAX_ECBS MAX_RECEIVE_ECBS + MAX_SEND_ECBS + 1
#define MAX_DATA_LENGTH 80
#define CONNECTED_MESSAGE WM_USER + 1 /*Message sent when connection in complete*/
#define DATA_SENT_MESSAGE WM_USER + 2
#define DATA_RECEIVED_MESSAGE WM_USER + 3
HWND mainHwnd; /* main parent window, used to send messages */
ECB
SPXReceiveECB[MAX_RECEIVE_ECBS],
SPXSendECB[MAX_SEND_ECBS],
SPXConnectECB,
SPXListenECB;
ECB
IPXReceiveECB[MAX_RECEIVE_ECBS],
IPXSendECB[MAX_SEND_ECBS];
SPXHeader
receiveSPXHeader[MAX_RECEIVE_ECBS],
sendSPXHeader[MAX_SEND_ECBS],
connectSPXHeader,
listenSPXHeader;
IPXHeader
receiveIPXHeader[MAX_RECEIVE_ECBS],
sendIPXHeader[MAX_SEND_ECBS];
struct SPXBufferType
{
int sequenceNumber;
char data[MAX_DATA_LENGTH];
} SPXReceiveBuffer[MAX_RECEIVE_ECBS],
SPXSendBuffer[MAX_SEND_ECBS];
struct IPXBufferType
{
int sequenceNumber;
char data[MAX_DATA_LENGTH];
} IPXReceiveBuffer[MAX_RECEIVE_ECBS],
IPXSendBuffer[MAX_SEND_ECBS];
/* Which protocol to use - user selected */
char bIPX, bTLI = 0;
/* set SPX as the default */
char bSPX = 1;
NWNET_ADDR internetAddress[10]; /* Address to send to */
char szLoginName[49]; /* Station name to send to */
BYTE immediateAddress[6]; /* Immediate Address used with IPX */
/* SPX ESR handler functions */
void FAR PASCAL SPXReceiveESRHandler (void);
void FAR PASCAL SPXSendESRHandler (void);
void FAR PASCAL SPXListenESRHandler (void);
void FAR PASCAL SPXConnectESRHandler (void);
void FAR PASCAL SPXTerminateESRHandler (void);
static FARPROC lpfnSPXReceiveESRHandler;
static FARPROC lpfnSPXSendESRHandler;
static FARPROC lpfnSPXListenESRHandler;
static FARPROC lpfnSPXConnectESRHandler;
static FARPROC lpfnSPXTerminateESRHandler;
/* IPX ESR handler functions */
void FAR PASCAL IPXReceiveESRHandler (void);
void FAR PASCAL IPXSendESRHandler (void);
static FARPROC lpfnIPXReceiveESRHandler;
static FARPROC lpfnIPXSendESRHandler;
/* internal SPX connection functions */
int SPXListen (void);
int SPXConnect (void);
int AmIFirst (void);
/* internal TLI connection functions */
int TLIListen (void);
int TLIConnect (void);
void TLITestForReceive ();
/* user interface function */
LONG FAR PASCAL WndProc (HWND, WORD, WORD, LONG);
BOOL FAR PASCAL CallDialogBoxProc (HWND, WORD, WORD, LONG);
BOOL FAR PASCAL ProtocolDialogBoxProc (HWND, WORD, WORD, LONG);
/* internal procedures */
int InitializeProtocol ();
int InitializeIPX ();
int InitializeSPX ();
int InitializeTLI ();
void SendDataPacket (char *);
void SendIPXDataPacket (char *);
void SendSPXDataPacket (char *);
void SendTLIDataPacket (char *);
void ProcessReceivedData ();
void ProcessIPXData ();
void ProcessSPXData ();
void ProcessTLIData ();
void TerminateConnection ();
void TerminateIPX ();
void TerminateSPX ();
void TerminateTLI ();
void Draw3DRect(HDC hDC,
int top,
int left,
int bottom,
int right,
int bInOut,
int RectWidth);
static HANDLE hInstance;
static FARPROC lpfnCallDialogBoxProc;
static FARPROC lpfnProtocolDialogBoxProc;
char szBuffer[300];
NWCCODE NWCcode;
char connectionIsInitialized = 0;
/* SPX Variables */
DWORD IPXTaskID;
WORD socket;
WORD SPXConnectionID;
struct SREGS sRegs;
struct WORDREGS wordRegs;
/* Global sequence number used sending and receiving packets to determine
which ECB should be used next and which sequenceNumber the app is waiting
for */
int sendSequenceNumber,
receiveSequenceNumber;
/* IPX Variables */
WORD destinationSocket;
/* TLI Variables */
int fh; /* file handle for sending and receiving */
/* semaphore and internet address variables */
NWCONN_HANDLE conn; /* connection handle to chosen server */
NWSEM_HANDLE semaphoreHandle;
HBRUSH hBkgndBrush = NULL; /* pattern brush used to paint window background */
HBITMAP hBkgndBitmap = NULL; /* bitmap used to paint window background */
WORD MySegment;
WORD far *I;
int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
LPSTR lpszCmdLine, int nCmdShow)
{
static char szAppName[] = "Chat";
HWND hwnd;
MSG msg;
WNDCLASS wndclass;
if (!hPrevInstance)
{
/* load the bitmap resource used to create our background patten brush */
hBkgndBitmap = LoadBitmap(hInstance, "bmpBkgnd");
/* create a brush from the background pattern bitmap */
hBkgndBrush = CreatePatternBrush(hBkgndBitmap);
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = (WNDPROC) WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon (hInstance, szAppName);
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
wndclass.hbrBackground = hBkgndBrush;
wndclass.lpszMenuName = szAppName;
wndclass.lpszClassName = szAppName;
RegisterClass (&wndclass);
}
hwnd = CreateWindow (szAppName, "Chat Program",
CS_HREDRAW | CS_VREDRAW | WS_SYSMENU | WS_MINIMIZEBOX,
50, // initial x position
50, // initial y position
550, // initial x size
350, // initial y size
NULL, // parent window handle
NULL, // window menu handle
hInstance, // program instance handle
NULL); // create parameters
ShowWindow (hwnd, nCmdShow);
UpdateWindow (hwnd);
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg);
DispatchMessage (&msg);
}
return msg.wParam;
} /* end WinMain */
/**************************************************************************/
/* */
/* MAIN WINDOW PROCEDURE - WndProc */
/* */
/**************************************************************************/
long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
{
WORD index; /* index returned when inserting into listbox */
static HWND hwndMessageList;
static HWND hwndCallButton;
static HWND hwndHangUpButton;
static HWND hwndProtocolButton;
static HWND hwndSendButton;
static HWND hwndMessageTitle;
static HWND hwndMessageText;
char data[MAX_DATA_LENGTH];
HDC hDC;
PAINTSTRUCT ps;
RECT Rect;
switch (message)
{
case WM_PAINT:
/* begin screen painting */
hDC = BeginPaint(hwnd, &ps);
/* draw the 3D rect around the message history list box */
Draw3DRect(hDC, 10, 5, 230, 425, 0, 1);
Draw3DRect(hDC, 0, 437, 300, 438, 0, 1);
/* draw the 3D rect around the message-to-send edit field */
GetClientRect(hwnd, &Rect);
Draw3DRect(hDC, Rect.bottom - 30, -1, Rect.bottom, Rect.right, 1, 1);
/* label the message-to-send with the word "message" */
/* drawn in transparent text */
SetBkMode(hDC, TRANSPARENT);
TextOut(hDC, 15, 287, "Message:", 8);
/* end screen painting */
EndPaint(hwnd, &ps);
return 0;
break;
case WM_CTLCOLOR:
/* change the background of the main screen push buttons to */
/* light gray to match the color of the background */
if ((LOWORD(lParam) != hwndMessageText) &&
(LOWORD(lParam) != hwndMessageList))
return((DWORD)GetStockObject(LTGRAY_BRUSH));
return(0);
break;
case WM_CREATE:
/* Lock the data segment containing the ECBs */
__asm mov MySegment, ds;
NWCcode = GlobalPageLock (MySegment);
if (NWCcode == 0)
{ /* GlobalPageLock failed */
MessageBox (hwnd, "GlobalPageLock failed", "Error", MB_OK);
}
mainHwnd = hwnd;
hInstance = ((LPCREATESTRUCT) lParam)->hInstance;
lpfnCallDialogBoxProc = MakeProcInstance
(CallDialogBoxProc,
hInstance);
lpfnProtocolDialogBoxProc = MakeProcInstance
(ProtocolDialogBoxProc,
hInstance);
/* intialize NWCALLS */
NWCcode = NWCallsInit ( (void NWFAR *) NULL, (void NWFAR *) NULL);
if (NWCcode)
{
sprintf (szBuffer, "Error intializing NWCALLS = %0X", NWCcode);
MessageBox (hwnd, szBuffer, "ERROR", MB_OK);
}
/* Create the main window components */
/* Create the messsage listbox */
hwndMessageList = CreateWindow("listbox",
NULL,
WS_VISIBLE | WS_CHILD |
LBS_STANDARD | WS_HSCROLL
| LBS_NOINTEGRALHEIGHT,
15,
20,
400,
200,
hwnd,
MESSAGE_LISTBOX,
((LPCREATESTRUCT) lParam) -> hInstance,
NULL);
/* Create the Call... Button */
hwndCallButton = CreateWindow("button",
"Call...",
WS_VISIBLE | WS_CHILD,
450,
20,
80,
30,
hwnd,
CALL_BUTTON,
((LPCREATESTRUCT) lParam) -> hInstance,
NULL);
/* Create the Hang Up Button */
hwndHangUpButton = CreateWindow("button",
"Hang Up",
WS_VISIBLE | WS_CHILD
| WS_DISABLED,
450,
70,
80,
30,
hwnd,
HANGUP_BUTTON,
((LPCREATESTRUCT) lParam) -> hInstance,
NULL);
/* Create the Protocol Button */
hwndProtocolButton = CreateWindow("button",
"Protocol...",
WS_VISIBLE | WS_CHILD,
450,
120,
80,
30,
hwnd,
PROTOCOL_BUTTON,
((LPCREATESTRUCT) lParam) -> hInstance,
NULL);
/* Create the Send Button */
hwndSendButton = CreateWindow("button",
"Send",
WS_VISIBLE | WS_CHILD | WS_DISABLED,
450,
283,
80,
24,
hwnd,
SEND_BUTTON,
((LPCREATESTRUCT) lParam) -> hInstance,
NULL);
/* Create the Message edit text */
hwndMessageText = CreateWindow("edit",
NULL,
WS_VISIBLE | WS_CHILD | WS_BORDER
| WS_DISABLED,
85,
283,
330,
24,
hwnd,
ETEXT_MESSAGE,
((LPCREATESTRUCT) lParam) -> hInstance,
NULL);
return 0;
break;
case WM_COMMAND:
switch (wParam)
{
case IDM_EXIT:
SendMessage(hwnd, WM_CLOSE, 0, 0L);
return 0;
break;
case CALL_BUTTON:
/* If a user to send to was not chosen (the cancel button
was pushed), do nothing. Else, continue by calling
InitializeProtocol */
if(DialogBox (hInstance, "CallDialogBox", hwnd,
lpfnCallDialogBoxProc) == FALSE)
return 0;
/* If IntializeProtocol fails, terminate the
connection, else, activate the hangup button and
disable the call and protocol buttons.*/
else if (!(InitializeProtocol()))
TerminateConnection();
else
{
EnableWindow (hwndCallButton, FALSE);
EnableWindow (hwndProtocolButton, FALSE);
EnableWindow (hwndHangUpButton, TRUE);
}
return 0;
break; /* end case CALL_BUTTON */
case PROTOCOL_BUTTON:
/* Call the dialog to let the user select a protocol */
DialogBox (hInstance, "ProtocolDialogBox", hwnd,
lpfnProtocolDialogBoxProc);
return TRUE;
break; /* end case PROTOCOL_BUTTON */
case HANGUP_BUTTON:
TerminateConnection();
/* After terminating, enable the call and protocol
buttons and disable the hang up and send buttons and the
message title and edit text */
EnableWindow (hwndCallButton, TRUE);
EnableWindow (hwndProtocolButton, TRUE);
EnableWindow (hwndHangUpButton, FALSE);
EnableWindow (hwndSendButton, FALSE);
EnableWindow (hwndMessageTitle, FALSE);
EnableWindow (hwndMessageText, FALSE);
/* Clear the message edit text and the list box */
SetDlgItemText (hwnd, ETEXT_MESSAGE, "");
SendMessage (hwndMessageList, LB_RESETCONTENT, 0, 0L);
connectionIsInitialized = FALSE;
return 0;
break; /* end case HANGUP_BUTTON */
case SEND_BUTTON:
/* Get the message to send */
GetDlgItemText (hwnd, ETEXT_MESSAGE, data, sizeof(data));
SendDataPacket (data);
/* Set the send message edit text to blank */
SetDlgItemText (hwnd, ETEXT_MESSAGE, "");
return TRUE;
break; /* end case SEND_BUTTON */
}
break; /* end switch case WM_COMMAND */
case CONNECTED_MESSAGE:
/* When the 2 sides are connected, enable the send buttons and the
message title and edit text */
EnableWindow (hwndSendButton, TRUE);
EnableWindow (hwndMessageTitle, TRUE);
EnableWindow (hwndMessageText, TRUE);
/* Add the connected string to the list box */
index = SendDlgItemMessage(mainHwnd, MESSAGE_LISTBOX,
LB_INSERTSTRING, -1,
(LONG)(LPSTR) "Ready to Chat.");
/* set the list box selection to the string inserted */
SendDlgItemMessage(mainHwnd, MESSAGE_LISTBOX,
LB_SETCURSEL, index,
(LONG)(LPSTR) 0);
return TRUE;
break; /* end case CONNECTED_MESSAGE */
case DATA_SENT_MESSAGE:
/* check the status of the send here */
return TRUE;
break; /* case DATA_SENT_MESSAGE */
case DATA_RECEIVED_MESSAGE:
/* process received data call the appropriate procedure
to place the received data in the list box */
ProcessReceivedData ();
return TRUE;
break; /* end case DATA_RECEIVED_MESSAGE */
case WM_TIMER:
TLITestForReceive();
return TRUE;
break; /* end case WM_TIMER */
case WM_DESTROY:
if (connectionIsInitialized)
TerminateConnection();
/* release the GDI objects that are used for the main */
/* window background pattern */
if (hBkgndBrush != NULL)
DeleteObject(hBkgndBrush);
if (hBkgndBitmap != NULL)
DeleteObject(hBkgndBitmap);
/* force Windows to send a WM_QUIT to end the message loop */
PostQuitMessage (0);
return 0;
break; /* end case WM_DESTROY */
} /* end switch for message */
return DefWindowProc (hwnd, message, wParam, lParam);
} /*end WndProc*/
/**************************************************************************/
/* */
/* CHAT DIALOG BOX PROCEDURE - CallDialogBoxProc */
/* */
/**************************************************************************/
BOOL FAR PASCAL CallDialogBoxProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
{
/* server list retrieval variables */
WORD i,j, reserved=0;
NWLOCAL_MODE reserved1;
NWLOCAL_SCOPE reserved2;
NWCONN_HANDLE connListBuffer[8];
WORD connListBufferSize, numConnections, connStatusBufferSize;
CONNECT_INFO connStatusBuffer;
char szServerName[49];
/* User list retrieval variables */
char objectName[49];
NWOBJ_TYPE objectType;
NWOBJ_ID objectID;
BYTE loginTime[7];
WORD index;
static WORD connNumberArray[1000]; /* Array to hold upto 1000 connection
numbers for a file server */
HWND hServerListBox; /* Handle to the serverListBox */
HWND hOKButton; /* Handle to the OKButton */
switch (message)
{
case WM_INITDIALOG:
/* Get list of servers to which currently attached */
connListBufferSize = sizeof (connListBuffer);
NWCcode = NWGetConnectionList (reserved,
(NWCONN_HANDLE NWFAR *) connListBuffer,
connListBufferSize,
(WORD NWFAR *) &numConnections);
if (NWCcode)
{
sprintf (szBuffer, "Error on NWGetConnectionList = %0X",
NWCcode);
MessageBox (hwnd, szBuffer, "ERROR", MB_OK);
}
/* Fill the server list box with the servers currently attached */
for (i=0;i<numConnections;i++)
{
NWCcode = NWGetConnectionStatus (connListBuffer[i],
(CONNECT_INFO NWFAR *) &connStatusBuffer,
connStatusBufferSize);
SendDlgItemMessage (hwnd, SERVER_LISTBOX,
LB_ADDSTRING, 0,
(LONG) (LPSTR) connStatusBuffer.serverName);
} /* end for */
return TRUE;
break; /* case WM_INITDIALOG */
case WM_COMMAND:
switch (wParam)
{
case SERVER_LISTBOX:
switch (HIWORD (lParam))
{
case LBN_SELCHANGE:
/* clear the user list box */
SendDlgItemMessage (hwnd, USER_LISTBOX,
LB_RESETCONTENT, 0,
(LONG) (LPSTR) NULL);
/* Disable the USER_LISTBOX from redrawing while
filling it with users */
SendDlgItemMessage (hwnd, USER_LISTBOX,
WM_SETREDRAW, FALSE, 0L);
/* Get the server name changed to */
index = (WORD) SendDlgItemMessage (hwnd,
SERVER_LISTBOX,
LB_GETCURSEL, 0, 0L);
(WORD) SendDlgItemMessage (hwnd, SERVER_LISTBOX,
LB_GETTEXT, index,
(LONG) (LPSTR) szServerName);
/* Disable the OK Button until a user is selected */
hOKButton = GetDlgItem (hwnd, OK_BUTTON);
EnableWindow (hOKButton, FALSE);
/* Disable the server list box while collecting */
hServerListBox = GetDlgItem (hwnd, SERVER_LISTBOX);
EnableWindow (hServerListBox, FALSE);
/* Specify in the status text to wait, while collecting */
SetDlgItemText (hwnd, STEXT_COLLECTING,
(LPSTR) "Please Wait. Collecting User Names...");
/* Get the connection handle of the server from which
to choose a user */
NWCcode = NWGetConnectionHandle (
(BYTE NWFAR *) szServerName,
reserved1,
(NWCONN_HANDLE NWFAR *) &conn,
(NWLOCAL_SCOPE NWFAR *) &reserved2);
/* Fill the user list box with users logged into
the selected server */
j=0;
for (i=1; i<=1000; i++)
{
NWCcode = NWGetConnectionInformation(conn, i,
(char NWFAR *) objectName,
(NWOBJ_TYPE NWFAR *) &objectType,
(NWOBJ_ID NWFAR *) &objectID,
(BYTE NWFAR *) loginTime);
if (NWCcode == SUCCESSFUL &&
objectType == OT_USER &&
strcmp (objectName, "NOT-LOGGED-IN"))
{
/* Add the user to the list box */
sprintf (szBuffer, "%d %s", i, objectName);
SendDlgItemMessage (hwnd, USER_LISTBOX,
LB_INSERTSTRING, -1,
(LONG) (LPSTR) szBuffer);
/* Update the parallel array */
connNumberArray[j] = i;
j++;
} /* end if */
} /* end for */
/* Specify in the status text to blank, after collecting */
SetDlgItemText (hwnd, STEXT_COLLECTING,
(LPSTR) "");
/* Enable the server list box after collecting */
hServerListBox = GetDlgItem (hwnd, SERVER_LISTBOX);
EnableWindow (hServerListBox, TRUE);
/* Enable the redraw of the USER_LISTBOX after
filling it with users */
SendDlgItemMessage (hwnd, USER_LISTBOX,
WM_SETREDRAW, TRUE, 0L);
return TRUE;
break; /* case LBN_SELCHANGE */
} /* end switch (wParam) */
break; /* case SERVER_LISTBOX */
case USER_LISTBOX:
switch (HIWORD (lParam))
{
case LBN_SELCHANGE:
/* Enable the OK Button when a user is selected */
hOKButton = GetDlgItem (hwnd, OK_BUTTON);
EnableWindow (hOKButton, TRUE);
return TRUE;
break; /* case LBN_SELCHANGE */
} /* end switch (wParam) */
break; /* case SERVER_LISTBOX */
case OK_BUTTON:
/* Get the LoginName of the chat partner */
index = (WORD) SendDlgItemMessage (hwnd,
USER_LISTBOX,
LB_GETCURSEL, 0, 0L);
(WORD) SendDlgItemMessage (hwnd, USER_LISTBOX,
LB_GETTEXT, index,
(LONG) (LPSTR) szBuffer);
/* cut the connection number out of the user string */
strcpy (szLoginName, (strchr (szBuffer, ' ') + 1));
/* Get the address of the station to send to */
/* Sets global internetAddress to address */
/* if successfully retrieved the internetAddress,
end the dialog with TRUE, else end the dialog
with false */
NWCcode = NWGetInternetAddress (conn,
connNumberArray[index],
(NWNET_ADDR NWFAR *) internetAddress);
if (NWCcode)
{
sprintf (szBuffer,
"Error on NWGetInternetAddress = %0X", NWCcode);
MessageBox (NULL, szBuffer, "ERROR", MB_OK);
EndDialog (hwnd, FALSE);
}
else
EndDialog (hwnd, TRUE);
return TRUE;
break; /* case OK_BUTTON */
case CANCEL_BUTTON:
EndDialog (hwnd, FALSE);
return TRUE;
break; /* end CANCEL_BUTTON */
} /*end switch for wParam */
break; /* case WM_COMMAND */
} /* end switch for message */
return FALSE;
} /*end CallDialogBoxProc*/
/**************************************************************************/
/* */
/* PROTOCOL DIALOG BOX PROCEDURE - ProtocolCallDialogBoxProc */
/* */
/**************************************************************************/
BOOL FAR PASCAL ProtocolDialogBoxProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
{
switch (message)
{
case WM_INITDIALOG:
/* set the default protocol to whichever is currently chosen.
SPX is the default before one is chosen by the user. */
if (bIPX)
SendDlgItemMessage(hwnd, RB_IPX, BM_SETCHECK, TRUE, 0L);
else if (bSPX)
SendDlgItemMessage(hwnd, RB_SPX, BM_SETCHECK, TRUE, 0L);
else
SendDlgItemMessage(hwnd, RB_TLI, BM_SETCHECK, TRUE, 0L);
return TRUE;
break; /* case WM_INITDIALOG */
case WM_COMMAND:
switch (wParam)
{
case OK_BUTTON:
/* Get the protocol to use */
if (SendDlgItemMessage(hwnd, RB_IPX, BM_GETCHECK, TRUE, 0L))
{
bIPX = 1;
bSPX = 0;
bTLI = 0;
}
else
if (SendDlgItemMessage(hwnd, RB_SPX, BM_GETCHECK, TRUE, 0L))
{
bSPX = 1;
bIPX = 0;
bTLI = 0;
}
else
{
bTLI =1;
bIPX = 0;
bSPX = 0;
}
EndDialog (hwnd, TRUE);
break; /* case OK_BUTTON */
case CANCEL_BUTTON:
EndDialog (hwnd, TRUE);
return TRUE;
break; /* end CANCEL_BUTTON */
} /*end switch for wParam */
break; /* case WM_COMMAND */
} /* end switch for message */
return FALSE;
} /*end CallDialogBoxProc*/
/**************************************************************************/
/* */
/* Protocol Initialization Procedure - Initialize Protocol */
/* */
/**************************************************************************/
int InitializeProtocol ()
{
WORD index; /* index of string inserted into list box */
/* Prepare the initialization string based on the chosen protocol */
if (bIPX)
sprintf (szBuffer, "IPX Init... Preparing to chat with %s",
szLoginName);
else if (bSPX)
sprintf (szBuffer, "SPX Init... Connecting with %s ....",
szLoginName);
else
sprintf (szBuffer, "TLI(SPXII) Init...Connecting with %s ....",
szLoginName);
/* Add the prepared string to the list box */
index = SendDlgItemMessage(mainHwnd, MESSAGE_LISTBOX,
LB_INSERTSTRING, -1,
(LONG)(LPSTR) szBuffer);
/* set the list box selection to the string inserted */
SendDlgItemMessage(mainHwnd, MESSAGE_LISTBOX,
LB_SETCURSEL, index,
(LONG)(LPSTR) 0);
connectionIsInitialized = TRUE;
if (bIPX)
return InitializeIPX();
else if (bSPX)
return InitializeSPX();
else
return InitializeTLI();
} /*end InitializeProtocol */
/**************************************************************************/
/* */
/* Data Packet Sending Procedure - SendDataPacket */
/* */
/**************************************************************************/
void SendDataPacket (char *dataToSend)
{
WORD index; /* index into list box */
strcpy (szBuffer, "YOU: ");
strcat (szBuffer, dataToSend);
index = SendDlgItemMessage(mainHwnd, MESSAGE_LISTBOX,
LB_INSERTSTRING, -1,
(LONG)(LPSTR) szBuffer);
/* set the list box selection to the string inserted */
SendDlgItemMessage(mainHwnd, MESSAGE_LISTBOX,
LB_SETCURSEL, index,
(LONG)(LPSTR) 0);
if (bIPX)
SendIPXDataPacket (dataToSend);
else if (bSPX)
SendSPXDataPacket (dataToSend);
else
SendTLIDataPacket (dataToSend);
} /*end InitializeProtocol */
/**************************************************************************/
/* */
/* Procedure to Process Received Data - ProcessReceivedData */
/* */
/**************************************************************************/
void ProcessReceivedData ()
{
if (bIPX)
ProcessIPXData ();
else if (bSPX)
ProcessSPXData ();
else
ProcessTLIData ();
} /*end ProcessReceiveData */
/**************************************************************************/
/* */
/* Protocol Termination - TerminateConnection */
/* */
/**************************************************************************/
void TerminateConnection ()
{
/* close the semaphore used in intialization to determine the first
instance in the function AmIFirst */
NWCcode = NWCloseSemaphore (conn, semaphoreHandle);
if (NWCcode)
{
sprintf (szBuffer, "Error on NWCloseSemaphore = %0X", NWCcode);
MessageBox (NULL, szBuffer, "ERROR", MB_OK);
}
if (bIPX)
TerminateIPX();
else if (bSPX)
TerminateSPX();
else
TerminateTLI();
} /*end InitializeProtocol */
/**************************************************************************/
/* */
/* IPX Protocol Initialization Procedure - InitializeIPX */
/* */
/**************************************************************************/
int InitializeIPX ()
{
WORD maxPacketSize;
int i,
imFirst; /* to determine which socket to use */
int transportTime;
maxPacketSize = sizeof(IPXHeader) + sizeof(IPXReceiveBuffer[0]);
IPXTaskID = 0x00;
NWCcode = IPXInitialize ( (DWORD FAR *) &IPXTaskID,
(WORD) MAX_ECBS,
(WORD) maxPacketSize);
if (NWCcode != SUCCESSFUL)
{
sprintf (szBuffer, "Error on IPXInitialize = %0X", NWCcode);
MessageBox (NULL, szBuffer, "ERROR", MB_OK);
return FALSE;
}
imFirst = AmIFirst();
/* if you are the first to run the program, use the listen socket, else
use the connect socket */
if (imFirst)
{
socket = LISTEN_SOCKET;
destinationSocket = CONNECT_SOCKET;
}
else
{
socket = CONNECT_SOCKET;
destinationSocket = LISTEN_SOCKET;
}
NWCcode = IPXOpenSocket (IPXTaskID, (WORD *) &socket,
(BYTE) LONG_LIVED);
if (NWCcode)
{
sprintf (szBuffer, "Error on IPXOpenSocket = %0X", NWCcode);
MessageBox (NULL, szBuffer, "ERROR", MB_OK);
return FALSE;
}
/* Get a handle to the send ESR to be used later on sends in
the SendIPXDataPacket function */
lpfnIPXSendESRHandler = MakeProcInstance ((FARPROC) IPXSendESRHandler,
hInstance);
/* Pre-Post all receive ECBs */
lpfnIPXReceiveESRHandler = MakeProcInstance (
(FARPROC) IPXReceiveESRHandler,
hInstance);
NWCcode = IPXGetLocalTarget (IPXTaskID, (BYTE FAR *) internetAddress,
(BYTE FAR *) immediateAddress,
(int FAR *) &transportTime);
if (NWCcode)
{
sprintf (szBuffer, "Error on IPXGetLocalTarget = %0X", NWCcode);
MessageBox (NULL, szBuffer, "ERROR", MB_OK);
return FALSE;
}
for (i=0; i<MAX_RECEIVE_ECBS; i++)
{
IPXReceiveECB[i].ESRAddress =
(void (far *) ()) lpfnIPXReceiveESRHandler;
IPXReceiveECB[i].socketNumber = socket;
memcpy (&IPXReceiveECB[i].immediateAddress, immediateAddress, 6);
IPXReceiveECB[i].fragmentCount = 2;
IPXReceiveECB[i].fragmentDescriptor[0].address = &receiveIPXHeader[i];
IPXReceiveECB[i].fragmentDescriptor[0].size = sizeof(IPXHeader);
IPXReceiveBuffer[i].sequenceNumber = 0xFF;
IPXReceiveECB[i].fragmentDescriptor[1].address = &IPXReceiveBuffer[i];
IPXReceiveECB[i].fragmentDescriptor[1].size = sizeof(IPXReceiveBuffer[0]);
IPXListenForPacket (IPXTaskID, &IPXReceiveECB[i]);
}
PostMessage (mainHwnd, CONNECTED_MESSAGE, 0, 0);
return TRUE;
} /*end InitializeIPX */
/**************************************************************************/
/* */
/* Send IPX Data Packet Procedure - SendIPXDataPacket */
/* */
/**************************************************************************/
void SendIPXDataPacket (char *dataToSend)
{
int i;
i = sendSequenceNumber;
/* If this ECB is currently in use, put up a message box and do not
send */
if (IPXSendECB[i].inUseFlag)
{
/* MessageBox (NULL, "All ECBs are in Use.\nData not sent.",
"Try Again", MB_OK);
*/
/* return; */
IPXRelinquishControl();
Yield();
}
IPXSendECB[i].ESRAddress =
(void (far *) ()) lpfnIPXSendESRHandler;
IPXSendECB[i].socketNumber = socket;
memcpy (&IPXSendECB[i].immediateAddress, immediateAddress, 6);
* (WORD *) sendIPXHeader[i].destination.socket = destinationSocket;
memcpy (&sendIPXHeader[i].destination.network, internetAddress, 10);
sendIPXHeader[i].packetType = 4; /* IPX packet type */
IPXSendECB[i].fragmentCount = 2;
IPXSendECB[i].fragmentDescriptor[0].address = &sendIPXHeader[i];
IPXSendECB[i].fragmentDescriptor[0].size = sizeof(IPXHeader);
IPXSendBuffer[i].sequenceNumber = i;
strcpy (IPXSendBuffer[i].data, dataToSend);
IPXSendECB[i].fragmentDescriptor[1].address = &IPXSendBuffer[i];
IPXSendECB[i].fragmentDescriptor[1].size = sizeof(IPXSendBuffer[i]);
IPXSendPacket (IPXTaskID, (ECB far *) &IPXSendECB[i]);
sendSequenceNumber = (sendSequenceNumber + 1) % MAX_SEND_ECBS;
} /*end SendIPXDataPacket */
/**************************************************************************/
/* */
/* IPX Data Processing Procedure - ProcessIPXData */
/* */
/**************************************************************************/
void ProcessIPXData ()
{
WORD index;
int i;
for (i=0; i < MAX_RECEIVE_ECBS; i++)
{
if (IPXReceiveBuffer[i].sequenceNumber == receiveSequenceNumber)
{
/* Add the person that sent the string to the data before adding
it to the list box */
sprintf (szBuffer, "%s: ", szLoginName);
strcat (szBuffer, IPXReceiveBuffer[i].data);
receiveSequenceNumber = (receiveSequenceNumber + 1) %
MAX_RECEIVE_ECBS;
index = SendDlgItemMessage(mainHwnd, MESSAGE_LISTBOX,
LB_INSERTSTRING, -1,
(LONG)(LPSTR) szBuffer);
if (index == LB_ERRSPACE)
{
MessageBox (mainHwnd, "No more space in list box.",
"End program", MB_OK);
PostMessage (mainHwnd, WM_COMMAND, HANGUP_BUTTON, 0);
}
/* set the list box selection to the string inserted */
SendDlgItemMessage(mainHwnd, MESSAGE_LISTBOX,
LB_SETCURSEL, index,
(LONG)(LPSTR) 0);
/* Repost the ECB */
IPXReceiveECB[i].ESRAddress =
(void (far *) ()) lpfnIPXReceiveESRHandler;
IPXReceiveECB[i].socketNumber = socket;
IPXReceiveECB[i].fragmentCount = 2;
IPXReceiveECB[i].fragmentDescriptor[0].address =
&receiveIPXHeader[i];
IPXReceiveECB[i].fragmentDescriptor[0].size = sizeof(IPXHeader);
IPXReceiveBuffer[i].sequenceNumber = 0xFF;
IPXReceiveECB[i].fragmentDescriptor[1].address =
&IPXReceiveBuffer[i];
IPXReceiveECB[i].fragmentDescriptor[1].size =
sizeof(IPXReceiveBuffer[i]);
IPXListenForPacket (IPXTaskID, &IPXReceiveECB[i]);
/* set the count back to 0 to search through the list for the
next message */
i = 0;
} /* end if */
} /*end for */
} /*end ProcessIPXData */
/**************************************************************************/
/* */
/* IPX Terminate Connection Procedure - TerminateIPX */
/* */
/**************************************************************************/
void TerminateIPX ()
{
IPXCloseSocket (IPXTaskID, socket);
NWCcode = IPXSPXDeinit (IPXTaskID);
if (NWCcode)
{
sprintf (szBuffer, "Error on IPXSPXDeinit = %0X", NWCcode);
MessageBox (NULL, szBuffer, "ERROR", MB_OK);
}
MessageBox(NULL, "Terminated IPX session", "goodbye", MB_OK);
} /* end TerminateIPX */
/**************************************************************************/
/* */
/* IPX Receive ESR Handler function - IPXReceiveESRHandler */
/* */
/**************************************************************************/
void FAR PASCAL IPXReceiveESRHandler ()
{
PostMessage (mainHwnd, DATA_RECEIVED_MESSAGE, 0, 0);
} /* end IPXReceiveESRHandler */
/**************************************************************************/
/* */
/* IPX Send ESR Handler function - IPXSendESRHandler */
/* */
/**************************************************************************/
void FAR PASCAL IPXSendESRHandler ()
{
PostMessage (mainHwnd, DATA_SENT_MESSAGE, 0, 0);
} /* end IPXSendESRHandler */
/**************************************************************************/
/* */
/* SPX Protocol Initialization Procedure - InitializeSPX */
/* */
/**************************************************************************/
int InitializeSPX ()
{
int i,
imFirst; /* to determine whether to listen or connect */
BYTE
majorRevisionNumber,
minorRevisionNumber;
WORD
maxSPXConnections,
availableConnections,
maxPacketSize;
maxPacketSize = sizeof(SPXHeader) + sizeof(SPXReceiveBuffer[0]);
IPXTaskID = 0x00;
NWCcode = SPXInitialize ( (DWORD FAR *) &IPXTaskID,
(WORD) MAX_ECBS,
(WORD) maxPacketSize,
(BYTE FAR *) &majorRevisionNumber,
(BYTE FAR *) &minorRevisionNumber,
(WORD FAR *) &maxSPXConnections,
(WORD FAR *) &availableConnections);
if (NWCcode != SPX_INSTALLED)
{
sprintf (szBuffer, "Error on SPXInitialize = %0X", NWCcode);
MessageBox (NULL, szBuffer, "ERROR", MB_OK);
return FALSE;
}
imFirst = AmIFirst();
/* if you are the first to run the program, listen, else connect */
if (imFirst)
socket = LISTEN_SOCKET;
else socket = CONNECT_SOCKET;
NWCcode = IPXOpenSocket (IPXTaskID, (WORD *) &socket,
(BYTE) LONG_LIVED);
if (NWCcode)
{
sprintf (szBuffer, "Error on IPXOpenSocket = %0X", NWCcode);
MessageBox (NULL, szBuffer, "ERROR", MB_OK);
return FALSE;
}
/* Get a handle to the send ESR to be used later on sends in
the SendSPXDataPacket function */
lpfnSPXSendESRHandler = MakeProcInstance ((FARPROC) SPXSendESRHandler,
hInstance);
/* Pre-Post all receive ECBs */
lpfnSPXReceiveESRHandler = MakeProcInstance ((FARPROC) SPXReceiveESRHandler,
hInstance);
for (i=0; i<MAX_RECEIVE_ECBS; i++)
{
SPXReceiveECB[i].ESRAddress =
(void (far *) ()) lpfnSPXReceiveESRHandler;
SPXReceiveECB[i].socketNumber = socket;
SPXReceiveECB[i].fragmentCount = 2;
SPXReceiveECB[i].fragmentDescriptor[0].address = &receiveSPXHeader[i];
SPXReceiveECB[i].fragmentDescriptor[0].size = sizeof(SPXHeader);
SPXReceiveBuffer[i].sequenceNumber = 0xFF;
SPXReceiveECB[i].fragmentDescriptor[1].address = &SPXReceiveBuffer[i];
SPXReceiveECB[i].fragmentDescriptor[1].size = sizeof(SPXReceiveBuffer[0]);
SPXListenForSequencedPacket (IPXTaskID, &SPXReceiveECB[i]);
}
/* listen or connect */
if (imFirst)
return SPXListen();
else return SPXConnect();
} /*end InitializeSPX */
/**************************************************************************/
/* */
/* Function to determine first instance of application - AmIFirst */
/* */
/**************************************************************************/
int AmIFirst ()
{
/* variables for opening semaphore */
char semaphoreName[20] = "CommSema";
NWSEM_INT initialValue;
NWNUMBER semaphoreOpenCount;
NWTICKS timeOutValue;
/* Open semaphore. If first to get the semaphore, use the LISTEN_SOCKET,
if second, use the CONNECT_SOCKET */
initialValue = 1; /* one handle to the resource allowed */
NWCcode = NWOpenSemaphore (conn,
(char NWFAR *) semaphoreName,
initialValue,
(NWSEM_HANDLE NWFAR *) &semaphoreHandle,
(NWNUMBER NWFAR *) &semaphoreOpenCount);
if (NWCcode != 0)
{
sprintf (szBuffer, "Open Semaphore, %s, failed", semaphoreName);
MessageBox (NULL, szBuffer, "Open Failure", MB_OK);
return FALSE;
}
/* Wait on the Semaphore */
timeOutValue = 0; /* no wait */
NWCcode = NWWaitOnSemaphore (conn,
semaphoreHandle,
timeOutValue);
if (NWCcode != 0) /* You're not first, semaphore already in use */
{
return FALSE;
}
else /* You're first */
{
return TRUE;
}
} /*end AmIFirst */
/**************************************************************************/
/* */
/* SPX Listen for Connection Function - SPXListen */
/* */
/**************************************************************************/
int SPXListen ()
{
lpfnSPXListenESRHandler = MakeProcInstance ((FARPROC) SPXListenESRHandler,
hInstance);
SPXListenECB.ESRAddress = (void (far *) ()) lpfnSPXListenESRHandler;
SPXListenECB.socketNumber = LISTEN_SOCKET;
SPXListenECB.fragmentCount = 1;
SPXListenECB.fragmentDescriptor[0].address = &listenSPXHeader;
SPXListenECB.fragmentDescriptor[0].size = sizeof(SPXHeader);
/* Listen for connection */
SPXListenForConnection (IPXTaskID, 0x00, 0xFF,
(ECB FAR *) &SPXListenECB);
return TRUE;
}
/**************************************************************************/
/* */
/* SPX Connect to the listening side Function - SPXConnect */
/* */
/**************************************************************************/
int SPXConnect ()
{
lpfnSPXConnectESRHandler = MakeProcInstance (
(FARPROC) SPXConnectESRHandler,
hInstance);
SPXConnectECB.ESRAddress = (void (far *) ()) lpfnSPXConnectESRHandler;
SPXConnectECB.socketNumber = CONNECT_SOCKET;
SPXConnectECB.fragmentCount = 1;
SPXConnectECB.fragmentDescriptor[0].address = &connectSPXHeader;
SPXConnectECB.fragmentDescriptor[0].size = sizeof(SPXHeader);
/* Copy network (4) and node (6) to the destination address */
memcpy (connectSPXHeader.destination.network, internetAddress, 10);
* (WORD *) connectSPXHeader.destination.socket = LISTEN_SOCKET;
/* Establish connection */
NWCcode = SPXEstablishConnection (IPXTaskID, 0x00, 0xFF,
(WORD FAR *) &SPXConnectionID,
(ECB far *) &SPXConnectECB);
if (NWCcode)
{
sprintf (szBuffer, "Error on SPXEstablishConnection = %0X", NWCcode);
MessageBox (NULL, szBuffer, "ERROR", MB_OK);
return FALSE;
}
return TRUE;
}
/**************************************************************************/
/* */
/* Send SPX Data Packet Procedure - SendSPXDataPacket */
/* */
/**************************************************************************/
void SendSPXDataPacket (char *dataToSend)
{
#define END_OF_MESSAGE 0x10 /* End of message marker for SPX */
int i;
i = sendSequenceNumber;
/* If this ECB is currently in use, put up a message box and do not
send */
if (SPXSendECB[i].inUseFlag)
{
/* MessageBox (NULL, "All ECBs are in Use.\nData not sent.",
"Try Again", MB_OK);
*/
/* return; */
IPXRelinquishControl();
Yield();
}
SPXSendECB[i].ESRAddress = (void (far *) ()) lpfnSPXSendESRHandler;
SPXSendECB[i].fragmentCount = 2;
SPXSendECB[i].fragmentDescriptor[0].address = &sendSPXHeader[i];
SPXSendECB[i].fragmentDescriptor[0].size = sizeof(SPXHeader);
SPXSendBuffer[i].sequenceNumber = i;
strcpy (SPXSendBuffer[i].data, dataToSend);
SPXSendECB[i].fragmentDescriptor[1].address = &SPXSendBuffer[i];
SPXSendECB[i].fragmentDescriptor[1].size = sizeof(SPXSendBuffer[i]);
sendSPXHeader[i].connectionControl = END_OF_MESSAGE;
sendSPXHeader[i].dataStreamType = 0x00;
SPXSendSequencedPacket (IPXTaskID, SPXConnectionID,
(ECB far *) &SPXSendECB[i]);
sendSequenceNumber = (sendSequenceNumber + 1) % MAX_SEND_ECBS;
} /*end SendSPXDataPacket */
/**************************************************************************/
/* */
/* SPX Data Processing Procedure - ProcessSPXData */
/* */
/**************************************************************************/
void ProcessSPXData ()
{
int i;
WORD index;
for (i=0; i < MAX_RECEIVE_ECBS; i++)
{
if (SPXReceiveBuffer[i].sequenceNumber == receiveSequenceNumber)
{
/* Add the person that sent the string to the data before adding
it to the list box */
sprintf (szBuffer, "%s: ", szLoginName);
strcat (szBuffer, SPXReceiveBuffer[i].data);
receiveSequenceNumber = (receiveSequenceNumber + 1) %
MAX_RECEIVE_ECBS;
index = SendDlgItemMessage(mainHwnd, MESSAGE_LISTBOX,
LB_INSERTSTRING, -1,
(LONG)(LPSTR) szBuffer);
if (index == LB_ERRSPACE)
{
MessageBox (mainHwnd, "No more space in list box.",
"End program", MB_OK);
PostMessage (mainHwnd, WM_COMMAND, HANGUP_BUTTON, 0);
}
/* set the list box selection to the string inserted */
SendDlgItemMessage(mainHwnd, MESSAGE_LISTBOX,
LB_SETCURSEL, index,
(LONG)(LPSTR) 0);
/* Repost the ECB */
SPXReceiveECB[i].ESRAddress =
(void (far *) ()) lpfnSPXReceiveESRHandler;
SPXReceiveECB[i].socketNumber = socket;
SPXReceiveECB[i].fragmentCount = 2;
SPXReceiveECB[i].fragmentDescriptor[0].address =
&receiveSPXHeader[i];
SPXReceiveECB[i].fragmentDescriptor[0].size = sizeof(SPXHeader);
SPXReceiveBuffer[i].sequenceNumber = 0xFF;
SPXReceiveECB[i].fragmentDescriptor[1].address =
&SPXReceiveBuffer[i];
SPXReceiveECB[i].fragmentDescriptor[1].size =
sizeof(SPXReceiveBuffer[0]);
SPXListenForSequencedPacket (IPXTaskID, &SPXReceiveECB[i]);
/* set the count back to 0 to search through the list for the
next message */
i = 0;
} /* end if */
} /*end for */
} /*end ProcessSPXData */
/**************************************************************************/
/* */
/* SPX Terminate Connection Procedure - TerminateSPX */
/* */
/**************************************************************************/
void TerminateSPX ()
{
lpfnSPXTerminateESRHandler = MakeProcInstance (
(FARPROC) SPXTerminateESRHandler,
hInstance);
SPXConnectECB.ESRAddress = (void (far *) ()) lpfnSPXTerminateESRHandler;
SPXConnectECB.fragmentCount = 1;
SPXConnectECB.fragmentDescriptor[0].address = &connectSPXHeader;
SPXConnectECB.fragmentDescriptor[0].size = sizeof(SPXHeader);
SPXTerminateConnection (IPXTaskID, SPXConnectionID,
(ECB FAR *) &SPXConnectECB);
IPXCloseSocket (IPXTaskID, socket);
NWCcode = IPXSPXDeinit (IPXTaskID);
if (NWCcode)
{
sprintf (szBuffer, "Error on IPXSPXDeinit = %0X", NWCcode);
MessageBox (NULL, szBuffer, "ERROR", MB_OK);
}
} /* end TerminateSPX */
/**************************************************************************/
/* */
/* SPX Receive ESR Handler function - SPXReceiveESRHandler */
/* */
/**************************************************************************/
void FAR PASCAL SPXReceiveESRHandler ()
{
PostMessage (mainHwnd, DATA_RECEIVED_MESSAGE, 0, 0);
} /* end SPXReceiveESRHandler */
/**************************************************************************/
/* */
/* SPX Send ESR Handler function - SPXSendESRHandler */
/* */
/**************************************************************************/
void FAR PASCAL SPXSendESRHandler ()
{
PostMessage (mainHwnd, DATA_SENT_MESSAGE, 0, 0);
} /* end SPXSendESRHandler */
/**************************************************************************/
/* */
/* SPX Listen ESR Handler function - SPXListenESRHandler */
/* */
/**************************************************************************/
void FAR PASCAL SPXListenESRHandler ()
{
WORD ECBSegment, ECBOffset;
ECB far *ECBIn;
__asm mov ECBSegment, es;
__asm mov ECBOffset, si;
/* Macros for Building an address with Microsoft C*/
_FP_OFF(ECBIn) = ECBOffset;
_FP_SEG(ECBIn) = ECBSegment;
/* Macro for building an address with Borland C*/
/* ECBIn = MK_FP (ECBSegment, ECBOffset);*/
/* Set the SPX connection ID to the established connection */
/* SPXConnectionID = *(WORD *) SPXListenECB.IPXWorkspace; */
SPXConnectionID = *(WORD FAR *) (ECBIn->IPXWorkspace);
PostMessage (mainHwnd, CONNECTED_MESSAGE, 0, 0);
} /* end SPXListenESRHandler */
/**************************************************************************/
/* */
/* SPX Connect ESR Handler function - SPXConnectESRHandler */
/* */
/**************************************************************************/
void FAR PASCAL SPXConnectESRHandler ()
{
PostMessage (mainHwnd, CONNECTED_MESSAGE, 0, 0);
} /* end SPXConnectESRHandler */
/**************************************************************************/
/* */
/* SPXTerminate ESR Handler function - SPXTerminateESRHandler */
/* */
/**************************************************************************/
void FAR PASCAL SPXTerminateESRHandler ()
{
MessageBox(NULL, "Connection Terminated", "goodbye", MB_OK);
} /* end SPXTerminateESRHandler */
/**************************************************************************/
/* */
/* TLI Protocol Initialization Procedure - InitializeTLI */
/* */
/**************************************************************************/
int InitializeTLI ()
{
int initStatus;
int imFirst;
fh = t_open ("/dev/nspx", O_RDWR, (struct t_info far *) NULL);
if (fh == -1)
{
t_error ("t_open failed");
return FALSE;
}
/* if you are the first to run the program, listen, else connect */
imFirst = AmIFirst();
/* Listen or Connect */
if (imFirst)
initStatus = TLIListen();
else initStatus = TLIConnect();
/* if the initialization is successful, put the connection into
non-blocking mode (for semi-asynchronous receiving), start a
receive timer and send a connected message */
if (initStatus)
{
t_nonblocking (fh);
if (!SetTimer (mainHwnd, TLI_RECEIVE_TIMER, 1000, NULL))
{
MessageBox (NULL, "No More timers available", "ERROR", MB_OK);
return FALSE;
}
PostMessage (mainHwnd, CONNECTED_MESSAGE, 0, 0);
}
return initStatus;
} /*end InitializeTLI */
/**************************************************************************/
/* */
/* TLI Listen for Connection Procedure - TLIListen */
/* */
/**************************************************************************/
int TLIListen ()
{
IPX_ADDR spx_addr;
SPX_OPTS spx_opts;
struct t_bind tbind;
struct t_call tcall;
*(WORD *) spx_addr.ipxa_socket = LISTEN_SOCKET;
tbind.addr.maxlen = sizeof(spx_addr);
tbind.addr.len = sizeof(spx_addr);
tbind.addr.buf = (char *) &spx_addr;
tbind.qlen = 1; /* Only 1 connection allowed */
if (t_bind (fh, (struct t_bind far *) &tbind,
(struct t_bind far *) &tbind) == -1)
{
t_error ("t_bind failed");
return FALSE;
}
tcall.addr.maxlen = sizeof(spx_addr);
tcall.addr.len = sizeof(spx_addr);
tcall.addr.buf = (char *) &spx_addr;
spx_opts.spx_connectionID[0] = 0;
spx_opts.spx_connectionID[1] = 0;
spx_opts.spx_allocationNumber[0] = 0;
spx_opts.spx_allocationNumber[1] = 0;
tcall.opt.maxlen = 0;
tcall.opt.len = 0;
tcall.opt.buf = (char *) NULL;
tcall.udata.maxlen = 0;
tcall.udata.len = 0;
tcall.udata.buf = (char *) NULL;
if (t_listen (fh, (struct t_call far *) &tcall) == -1)
{
t_error ((char far *) "t_listen failed");
return FALSE;
}
if (t_accept (fh, fh, (struct t_call far *) &tcall) == -1)
{
t_error ((char far *) "t_accept failed");
return FALSE;
}
return TRUE;
} /* end TLIListen */
/**************************************************************************/
/* */
/* TLI Connect Procedure - TLIConnect */
/* */
/**************************************************************************/
int TLIConnect ()
{
IPX_ADDR spx_addr;
SPX_OPTS spx_opts;
struct t_bind tbind;
struct t_call tcall;
*(WORD *) spx_addr.ipxa_socket = CONNECT_SOCKET;
tbind.addr.len = sizeof(spx_addr);
tbind.addr.maxlen = sizeof(spx_addr);
tbind.addr.buf = (char *) &spx_addr;
if (t_bind (fh, (struct t_bind far *) &tbind,
(struct t_bind far *) &tbind) == -1)
{
t_error ("t_bind failed");
return FALSE;
}
*(WORD *) spx_addr.ipxa_socket = LISTEN_SOCKET;
/* copy network (4) and node (6) to the destination address */
memcpy (&spx_addr.ipxa_net, internetAddress, 10);
tcall.addr.maxlen = sizeof (spx_addr);
tcall.addr.len = sizeof (spx_addr);
tcall.addr.buf = (char *) &spx_addr;
spx_opts.spx_connectionID[0] = 0;
spx_opts.spx_connectionID[1] = 0;
spx_opts.spx_allocationNumber[0] = 0;
spx_opts.spx_allocationNumber[1] = 0;
tcall.opt.maxlen = 0;
tcall.opt.len = 0;
tcall.opt.buf = (char *) NULL;
tcall.udata.maxlen = 0;
tcall.udata.len = 0;
tcall.udata.buf = (char *) NULL;
if (t_connect (fh, (struct t_call far *) &tcall,
(struct t_call far *) &tcall) == -1)
{
t_error ((char far *) "t_connect failed");
return FALSE;
}
return TRUE;
} /* end TLIConnect */
/**************************************************************************/
/* */
/* Send TLI Data Packet Procedure - SendTLIDataPacket */
/* */
/**************************************************************************/
void SendTLIDataPacket (char *dataToSend)
{
SPXSendBuffer[0].sequenceNumber = sendSequenceNumber;
strcpy (SPXSendBuffer[0].data, dataToSend);
if (t_snd (fh, (char far *) &SPXSendBuffer[0], sizeof(SPXSendBuffer[0]),
0) == -1)
{
t_error ("t_snd Failed ");
}
else
sendSequenceNumber = (sendSequenceNumber + 1) % MAX_SEND_ECBS;
} /*end SendTLIDataPacket */
/**************************************************************************/
/* */
/* TLI Test for Receive Procedure - TLITestForReceive */
/* */
/**************************************************************************/
void TLITestForReceive ()
{
WORD index;
int flags;
int i;
i = receiveSequenceNumber;
/* if data has been received, add it to the list box */
if (t_rcv (fh, (char far *) &SPXReceiveBuffer[i],
sizeof(SPXReceiveBuffer[i]), (int far *) &flags) != -1)
{
/* Add the person that sent the string to the data before adding
it to the list box */
sprintf (szBuffer, "%s: ", szLoginName);
strcat (szBuffer, SPXReceiveBuffer[i].data);
receiveSequenceNumber = (receiveSequenceNumber + 1) %
MAX_RECEIVE_ECBS;
index = SendDlgItemMessage(mainHwnd, MESSAGE_LISTBOX,
LB_INSERTSTRING, -1,
(LONG)(LPSTR) szBuffer);
if (index == LB_ERRSPACE)
{
MessageBox (mainHwnd, "No more space in list box.",
"End program", MB_OK);
PostMessage (mainHwnd, WM_COMMAND, HANGUP_BUTTON, 0);
}
/* set the list box selection to the string inserted */
SendDlgItemMessage(mainHwnd, MESSAGE_LISTBOX,
LB_SETCURSEL, index,
(LONG)(LPSTR) 0);
}
} /*end TLITestForReceive */
/**************************************************************************/
/* */
/* TLI Data Processing Procedure - ProcessTLIData */
/* */
/**************************************************************************/
void ProcessTLIData ()
{
} /*end ProcessTLIData */
/**************************************************************************/
/* */
/* TLI Terminate Connection Procedure - TerminateTLI */
/* */
/**************************************************************************/
void TerminateTLI ()
{
KillTimer (mainHwnd, TLI_RECEIVE_TIMER);
if (t_close (fh) == -1)
{
t_error ("t_close Failed ");
}
} /* end TerminateTLI */
/***************************************************************************/
/* Draw3DRect */
/* This routine draws a 3D rectangle as described */
/***************************************************************************/
void Draw3DRect(HDC hDC,
int top,
int left,
int bottom,
int right,
int bInOut, /* 0 = 3D IN, 1 = 3D OUT */
int RectWidth)
{
RECT OurRect;
RECT TempRECT;
short i;
HPEN hDkGrayPen;
/* create a dark gray pen for drawing 3D box shadows */
hDkGrayPen = CreatePen(PS_SOLID, /* style */
0, /* width (0 = 1 pixel) */
RGB(128, 128, 128)); /* color */
/* make a copy of the RECT */
OurRect.top = top;
OurRect.left = left;
OurRect.bottom = bottom;
OurRect.right = right;
/* set the brush to light gray */
SelectObject(hDC, GetStockObject(NULL_PEN));
SelectObject(hDC, GetStockObject(LTGRAY_BRUSH));
/* copy the rect coordinates for the 3D rect */
memcpy(&TempRECT, &OurRect, sizeof(TempRECT));
/* adjust coordinates to always fill only interior of rect */
TempRECT.left++;
TempRECT.top++;
TempRECT.right++;
/* clear the area of the 3D box */
Rectangle(hDC, TempRECT.left, TempRECT.top,
TempRECT.right, TempRECT.bottom+1);
/* draw as many 3D boxes as specified */
for (i = 0; i < RectWidth; i++)
{
/* set the line color for left and top edges */
if (bInOut == 0)
SelectObject(hDC, hDkGrayPen);
else
SelectObject(hDC, GetStockObject(WHITE_PEN));
/* draw the left edge from bottom to top */
MoveTo(hDC, OurRect.left, OurRect.bottom);
LineTo(hDC, OurRect.left, OurRect.top);
/* draw the top edge from left to right */
LineTo(hDC, OurRect.right, OurRect.top);
/* set the line color for right and bottom edges */
if (bInOut == 0)
SelectObject(hDC, GetStockObject(WHITE_PEN));
else
SelectObject(hDC, hDkGrayPen);
/* draw the right edge from top to bottom */
LineTo(hDC, OurRect.right, OurRect.bottom);
/* draw the bottom edge from right to left */
LineTo(hDC, OurRect.left, OurRect.bottom);
/* adjust rect coordinates to draw next 3D rect inside */
/* this rect */
OurRect.left++;
OurRect.top++;
OurRect.right--;
OurRect.bottom--;
}
/* release our dark gray pen */
DeleteObject(hDkGrayPen);
}