www.pudn.com > ipxchat.zip > LISTEN.C, change:1997-10-05,size:13788b


// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO 
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 
// PARTICULAR PURPOSE. 
// 
// Copyright (C) 1993-1997  Microsoft Corporation.  All Rights Reserved. 
// 
//  MODULE:   listen.c 
// 
//  PURPOSE:   Displays the "Listen" dialog box 
// 
//  FUNCTIONS: 
//    CmdListen          - Displays the "Listen" dialog box. 
//    Listen             - Processes messages for "Listen" dialog box. 
//    MsgListenInit      - Centers dialog and initializes edit controls. 
//    MsgListenConnected - Handles Connected message when socket is connected. 
//    MsgListenCommand   - Process WM_COMMAND message sent to the listen box. 
//    CmdListenDone      - Free the listen box and related data. 
//    CmdListenNow       - Sets up listen on specified socket 
// 
//  COMMENTS: 
// 
// 
 
#include <windows.h>            // required for all Windows applications 
#include <windowsx.h> 
#include <wsipx.h> 
#include <stdlib.h> 
#include <stdio.h> 
#include "globals.h"            // prototypes specific to this application 
 
LRESULT CALLBACK Listen(HWND, UINT, WPARAM, LPARAM); 
LRESULT MsgListenInit(HWND, UINT, WPARAM, LPARAM); 
LRESULT MsgListenCommand(HWND, UINT, WPARAM, LPARAM); 
LRESULT MsgListenConnected(HWND, UINT, WPARAM, LPARAM); 
LRESULT CmdListenNow(HWND, WORD, WORD, HWND); 
LRESULT CmdListenDone(HWND, WORD, WORD, HWND); 
 
// Listen dialog message table definition. 
MSD rgmsdListen[] = 
{ 
    {WM_COMMAND,    MsgListenCommand}, 
    {WM_INITDIALOG, MsgListenInit}, 
    {LDM_CONNECTED, MsgListenConnected} 
}; 
 
MSDI msdiListen = 
{ 
    sizeof(rgmsdListen) / sizeof(MSD), 
    rgmsdListen, 
    edwpNone 
}; 
 
// Listen dialog command table definition. 
CMD rgcmdListen[] = 
{ 
    {IDOK,     CmdListenNow}, 
    {IDCANCEL, CmdListenDone} 
}; 
 
CMDI cmdiListen = 
{ 
    sizeof(rgcmdListen) / sizeof(CMD), 
    rgcmdListen, 
    edwpNone 
}; 
 
// Module specific "globals"  Used when a variable needs to be 
// accessed in more than one handler function. 
 
HFONT hfontDlg; 
 
// 
//  FUNCTION: CmdListen(HWND, WORD, WORD, HWND) 
// 
//  PURPOSE: Displays the "Listen" dialog box 
// 
//  PARAMETERS: 
//    hwnd      - Window handle 
//    wCommand  - IDM_LISTEN          (unused) 
//    wNotify   - Notification number (unused) 
//    hwndCtrl  - NULL                (unused) 
// 
//  RETURN VALUE: 
// 
//    Always returns 0 - Message handled 
// 
//  COMMENTS: 
//    To process the IDM_LISTEN message, call DialogBox() to display the 
//    Listen dialog box. 
 
LRESULT CmdListen(HWND hwnd, WORD wCommand, WORD wNotify, HWND hwndCtrl) 
{ 
    HMENU hmenu; 
 
    SetWindowText(hwnd, "IPX Chat Server");     // Change title bar text 
     
    // Start Dialog 
    if(DialogBox(hInst, "ListenBox", hwnd, (DLGPROC)Listen)) 
    { 
 
        // Dialog got a connection!  Set Message to indicate 
        // when we have data to read, or if the connection is 
        // closed on us. 
        if (WSAAsyncSelect(sock, 
                           hwnd, 
                           MW_DATAREADY, 
                           FD_READ | FD_CLOSE) == SOCKET_ERROR)  
        { 
            MessageBox(hwnd, "WSAAsyncSelect Failed!", NULL, MB_OK); 
            CleanUp(); 
            return 0; 
        } 
 
        // Fix menus 
        hmenu = GetMenu(hwnd); 
        EnableMenuItem(hmenu, IDM_CONNECT, MF_GRAYED); 
        EnableMenuItem(hmenu, IDM_LISTEN, MF_GRAYED); 
        EnableMenuItem(hmenu, IDM_DISCONNECT, MF_ENABLED); 
        return 0; 
    } 
 
    // Listen Failed 
    SetWindowText(hwnd, szTitle); 
    return 0; 
} 
 
 
// 
//  FUNCTION: Listen(HWND, UINT, WPARAM, LPARAM) 
// 
//  PURPOSE:  Processes messages for "Listen" dialog box. 
// 
//  PARAMETERS: 
//    hdlg - window handle of the dialog box 
//    wMessage - type of message 
//    wparam - message-specific information 
//    lparam - message-specific information 
// 
//  RETURN VALUE: 
//    TRUE - message handled 
//    FALSE - message not handled 
// 
//  COMMENTS: 
// 
//     Gets port information from user and then listens 
// 
//     Listen when user clicks on the OK button.  Kill Dialog when connection 
//     established. 
// 
 
LRESULT CALLBACK Listen(HWND hdlg, UINT uMessage, WPARAM wparam, LPARAM lparam) 
{ 
    return DispMessage(&msdiListen, hdlg, uMessage, wparam, lparam); 
} 
 
 
// 
//  FUNCTION: MsgListenInit(HWND, UINT, WPARAM, LPARAM) 
// 
//  PURPOSE: To center dialog and limit size of edit controls and initialize 
// 
//  PARAMETERS: 
//    hdlg - The window handing the message. 
//    uMessage - The message number. (unused). 
//    wparam - Message specific data (unused). 
//    lparam - Message specific data (unused). 
// 
//  RETURN VALUE: 
//    Always returns 0 - message handled. 
// 
//  COMMENTS: 
//    Set size of edit controls for the following 
//           Socket   4  chars (2 2-digit hex numbers) 
// 
 
LRESULT MsgListenInit(HWND hdlg, UINT uMessage, WPARAM wparam, LPARAM lparam) 
{ 
 
    // Create a font to use 
    hfontDlg = CreateFont(14, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0,  
                          VARIABLE_PITCH | FF_SWISS, ""); 
 
    // Center the dialog over the application window 
    CenterWindow (hdlg, GetWindow (hdlg, GW_OWNER)); 
      
    // Initialize Socket Addresses 
    SetDlgItemText(hdlg, LD_SOCKET, szListenSocket); 
 
    // Limit input to proper size strings 
    SendDlgItemMessage(hdlg, LD_SOCKET, EM_LIMITTEXT, 4, 0); 
 
    return (TRUE); 
} 
 
// 
//  FUNCTION: MsgListenConnected(HWND, UINT, WPARAM, LPARAM) 
// 
//  PURPOSE: To handle connected message when socket is connected 
// 
//  PARAMETERS: 
//    hdlg - The window handing the message. 
//    uMessage - The message number. (unused). 
//    wparam - Message specific data (unused). 
//    lparam - Message specific data (unused). 
// 
//  RETURN VALUE: 
//    Always returns 0 - message handled. 
// 
//  COMMENTS: 
//    Performs accept() on incoming socket 
// 
 
LRESULT MsgListenConnected(HWND hdlg, UINT uMessage, WPARAM wparam, LPARAM lparam) 
{ 
    char outtext[128]; 
 
    SetDlgItemText(hdlg, 
                   LD_STATUS, 
                   "Client Connected!"); 
 
    SetDlgItemText(hdlg, 
                   LD_STATUS, 
                   "Calling accept()"); 
 
    pRemAddr = (PSOCKADDR_IPX)&addr; 
    addrlen = sizeof(addr); 
 
    // Accept connection 
    if ((sock = accept(SrvSock, (struct sockaddr *)pRemAddr, &addrlen)) == INVALID_SOCKET) 
    { 
        // accept() failed -- show status and clean up dialog 
        sprintf(outtext, "Accept() failed, error %u",WSAGetLastError()); 
        SetDlgItemText(hdlg, 
                       LD_STATUS, 
                       outtext); 
        closesocket(SrvSock); 
        WSACleanup(); 
        EnableWindow(GetDlgItem(hdlg, IDOK), TRUE); 
        EnableWindow(GetDlgItem(hdlg, LD_SOCKET), TRUE); 
        SetFocus(GetDlgItem(hdlg, LD_SOCKET)); 
        return(TRUE); 
    } 
 
    // We're connected! 
    GetAddrString(pRemAddr, outtext); 
    lstrcat(outtext, " connected!"); 
 
    SetDlgItemText(hdlg, 
                   LD_STATUS, 
                   outtext); 
           
    EndDialog(hdlg, TRUE);          // Exit the dialog 
    DeleteObject (hfontDlg);        // Drop font 
    return (TRUE); 
} 
 
// 
//  FUNCTION: MsgListenCommand(HWND, UINT, WPARAM, LPARAM) 
// 
//  PURPOSE: Process WM_COMMAND message sent to the Listen box. 
// 
//  PARAMETERS: 
//    hwnd - The window handing the message. 
//    uMessage - The message number. (unused). 
//    wparam - Message specific data (unused). 
//    lparam - Message specific data (unused). 
// 
//  RETURN VALUE: 
//    Always returns 0 - message handled. 
// 
//  COMMENTS: 
//    Uses this DispCommand function defined in wndproc.c combined 
//    with the cmdiListen structure defined in this file to handle 
//    the command messages for the Listen dialog box. 
// 
 
LRESULT MsgListenCommand(HWND   hwnd,  
                        UINT   uMessage,  
                        WPARAM wparam,  
                        LPARAM lparam) 
{ 
    return DispCommand(&cmdiListen, hwnd, wparam, lparam); 
} 
 
// 
//  FUNCTION: CmdListenDone(HWND, WORD, HWND) 
// 
//  PURPOSE: Free the Listen box and related data. 
// 
//  PARAMETERS: 
//    hdlg - The window handling the command. 
//    wCommand - The command to be handled (unused). 
//    wNotify   - Notification number      (unused) 
//    hwndCtrl - NULL                      (unused). 
// 
//  RETURN VALUE: 
//    Always returns TRUE. 
// 
//  COMMENTS: 
//    Cleans up sockets then calls EndDialog to finish the dialog session. 
// 
 
LRESULT CmdListenDone(HWND hdlg, WORD wCommand, WORD wNotify, HWND hwndCtrl) 
{ 
 
    closesocket(SrvSock);    // Free any aborted socket resources 
    WSACleanup(); 
    DeleteObject (hfontDlg); // Drop the font 
    EndDialog(hdlg, FALSE);  // Exit Dialog -- rtrn false since no connection 
    return TRUE; 
} 
 
// 
//  FUNCTION: CmdListenNow(HWND, WORD, WORD, HWND) 
// 
//  PURPOSE: Handles ID_OK message and listens on the specified socket 
// 
//  PARAMETERS: 
//    hwnd - The window handling the command. 
//    wCommand - The command to be handled (unused). 
//    wNotify   - Notification number (unused) 
//    hwndCtrl - NULL (unused). 
// 
//  RETURN VALUE: 
//    Always returns TRUE. 
// 
//  COMMENTS: 
//    Shows Listening address on status bar when listen is successful. 
// 
 
LRESULT CmdListenNow(HWND hdlg, WORD wCommand, WORD wNotify, HWND hwndCtrl) 
{ 
    char szXferBuffer[5]; 
    WORD wVersionRequested; 
    WSADATA wsaData; 
    char outtext[80]; 
 
    // Get Socket Address 
    GetDlgItemText(hdlg, 
         LD_SOCKET, 
         szXferBuffer, 
         13); 
    wVersionRequested = MAKEWORD(1, 1); 
 
    SetDlgItemText(hdlg, 
                  LD_STATUS, 
                  "Calling WSAStartup"); 
 
    // Initializes winsock dll 
    if(WSAStartup(wVersionRequested, &wsaData) == SOCKET_ERROR) 
    { 
 
        SetDlgItemText(hdlg, 
                       LD_STATUS, 
                       "WSAStartup failed"); 
        return (TRUE); 
    } 
 
    SetDlgItemText(hdlg, 
          LD_STATUS, 
          "WSAStartup Succeeded"); 
 
    SetDlgItemText(hdlg, 
          LD_STATUS, 
          "Calling socket()"); 
 
    // Allocate socket handle 
    SrvSock = socket(AF_IPX,         // IPX Family 
                     SOCK_SEQPACKET, // Gives message mode transfers 
                     NSPROTO_SPX);   // SPX is connection oriented transport 
 
    if(SrvSock == INVALID_SOCKET) { 
        SetDlgItemText(hdlg, 
                       LD_STATUS, 
                       "ERROR on socket()"); 
        WSACleanup(); 
        return(TRUE); 
    } 
 
    SetDlgItemText(hdlg, 
                   LD_STATUS, 
                   "socket() Succeeded"); 
 
    // Set up socket address to bind to 
    memset(&addr, 0, sizeof(addr));    // Clear address 
    pSockAddr = (PSOCKADDR_IPX)&addr;  // Set pointer 
    pSockAddr->sa_family = AF_IPX;     // IPX Family 
    // Make sure socket number is in network order 
    AtoH(szXferBuffer, (char *)&pSockAddr->sa_socket, 2); 
 
    SetDlgItemText(hdlg, 
                   LD_STATUS, 
                   "Calling bind()"); 
 
    // Bind to socket address 
    if(bind(SrvSock,  
            (PSOCKADDR) pSockAddr,  
            sizeof(SOCKADDR_IPX)) == SOCKET_ERROR) 
    { 
        SetDlgItemText(hdlg, 
                       LD_STATUS, 
                       "Error on bind()"); 
        closesocket(SrvSock); 
        WSACleanup(); 
        return(TRUE); 
    } 
 
    SetDlgItemText(hdlg, 
                   LD_STATUS, 
                   "bind() Succeeded"); 
 
    SetDlgItemText(hdlg, 
                   LD_STATUS, 
                   "Calling listen()"); 
 
    // Set up listen queue - this app only supports one connection so 
    // queue length is set to 1. 
    if (listen(SrvSock, 1) == SOCKET_ERROR) 
    { 
        sprintf(outtext, "FAILURE: listen() returned %u", WSAGetLastError()); 
        SetDlgItemText(hdlg,                        
                       LD_STATUS, 
                       outtext); 
        closesocket(SrvSock); 
        WSACleanup(); 
        return(TRUE); 
    } 
 
    SetDlgItemText(hdlg, 
                   LD_STATUS, 
                   "listen() succeeded"); 
 
    SetDlgItemText(hdlg, 
                   LD_STATUS, 
                   "Calling WSAAsyncSelect()"); 
 
    // Specify message to be posted when client connects 
    if(WSAAsyncSelect(SrvSock,  
                      hdlg,  
                      LDM_CONNECTED,  
                      FD_ACCEPT) == SOCKET_ERROR) 
    { 
        SetDlgItemText(hdlg, 
                       LD_STATUS, 
                       "WSAAsyncSelect() failed"); 
        closesocket(SrvSock); 
        WSACleanup(); 
        return(TRUE); 
    } 
 
    SetDlgItemText(hdlg, 
                   LD_STATUS, 
                   "WSAAsyncSelect() succeeded"); 
 
    addrlen = sizeof(addr); 
 
    // Get full network.number.socket address 
    if(getsockname(SrvSock,&addr,&addrlen) == SOCKET_ERROR) 
    { 
        lstrcpy(outtext, "ERROR getsocketname()"); 
    } 
    else 
    { 
        lstrcpy(outtext, "Listening on "); 
        GetAddrString((PSOCKADDR_IPX)&addr, outtext + lstrlen(outtext)); 
    } 
 
    SetDlgItemText(hdlg, 
                   LD_STATUS, 
                   outtext); 
 
     
    SetFocus(GetDlgItem(hdlg, IDCANCEL));             // Give Cancel Button focus 
    EnableWindow(GetDlgItem(hdlg, IDOK), FALSE);      // Grey OK button 
    EnableWindow(GetDlgItem(hdlg, LD_SOCKET), FALSE); // Grey Socket Edit control 
    return (TRUE); 
}