---------------------------------------
WSASIMPL.DLL: sample DLL over WinSock
-------------------------------------

This DLL and the simple test program (SIMPLTST.EXE) are desribed
in Chapter 11, "DLLs over WinSock," in _Windows Sockets Network 
Programming_  by Bob Quinn and Dave Shute (published by Addison-
Wesley, Reading, MA ISBN: 0-201-63372-8)

What it does: The WSASIMPL DLL rovides a simple API for
 elemental network functionality using TCP: connect, send or receive
 data, and disconnect.

What it illustrates: The main purpose of WSASIMPL is to
 illustrate how to create a DLL that runs over WinSock, and prevents
 reentrant messages from being sent to the application calling
 the DLL over WinSock. It uses windows subclassing to capture keyboard
 and mouse messages while blocking network operations are underway.

How to Use it: Here are short descriptions along with the
 prototypes for the functions in the simplified WinSock API that
 WSASIMPL.DLL provides:

SOCKET WINAPI ConnectTCP(LPSTR szDestination, LPSTR szService);
 ConnectTCP() calls the WinSock WSAStartup() function to register
 the task with the WinSock DLL, gets a socket handle with socket(),
 resolves the destination host name or formats an address using
 the GetAddr() function from the sample WINSOCKX library, and resolves
 the destination service or formats the port number with the WINSOCKX
 GetPort() function. When all these operations succeed, ConnectTCP()
 returns a socket handle; when any step fails the function returns
 INVALID_SOCKET.

int WINAPI SendData (SOCKET hSock, LPSTR lpOutBuf, int cbTotalToSend); 
 SendData() sends cbTotalToSend data bytes on the hSock socket
 handle, from the buffer lpOutBuf. When it succeeds, it returns
 the number of bytes sent, and when it fails it returns SOCKET_ERROR.

int WINAPI RecvData (SOCKET hSock, LPSTR lpInBuf, int cbTotalToRecv, int nTimeout); 
 RecvData() recieves up to cbTotalToRecv data bytes on the
 hSock socket handle, into the buffer lpInBuf, until the nTimeout
 period (in milliseconds) expires. It returns the number of bytes
 received on success, and SOCKET_ERROR on failure (timeout is an
 error condition).

int WINAPI CloseTCP (SOCKET hSock, LPSTR lpInBuf,int len);
 CloseTCP() is almost the same function as CloseConn() in the
 #WINSOCKX">WINSOCKX.LIB WinSock subroutine library.
 It attempts a graceful close of the TCP connection on socket hSock
 by calling shutdown() with how=1 to stop sends but allow
 receives, then it calls recv() to read data (up to len)
 into the buffer lpInBuf, if provided. When recv() fails with any
 error, or returns 0 to indicate closure from the remote, CloseTCP()
 then calls closesocket() to free the resources associated with
 the socket handle.

The SIMPLTST sample application connects to an echo server, sends
data, and reads it back. The relevant code for this application
is as follows:

    SOCKET hSock;
    char szHost[MAXHOSTNAME];
    char achOutBuf[BUFSIZE], achInBuf[BUFSIZE];

    hSock = ConnectTCP((LPSTR)szHost, (LPSTR)"echo");
    if (hSock != INVALID_SOCKET) {
        int nRet;
        SendData(hSock, achOutBuf, BUFSIZE);
        RecvData(hSock, achInBuf, BUFSIZE);
        CloseTCP(hSock, 0, 0);
    }

Known Problems: WSASIMPL.DLL subclasses the active window
 when ConnectTCP() is called to avoid reentrant messages. We avoid
 problems in our subclassed window procedure by noting receipt
 of a WM_DESTROY message. Also note that because WSASIMPL.DLL uses
 blocking operation mode, it imposes the typical limitations on
 each task (e.g. while any blocking operation is outstanding, other
 WinSock calls from the same task or thread fail with WSAEINPROGRESS).

File List: 
 WSASIMPL\SIMPLTST.DEF 
 WSASIMPL\SIMPLTST.ICO 
 WSASIMPL\SIMPLTST.RC 
 WSASIMPL\SIMPLTST.C 
 WSASIMPL\SIMPLTST.MAK Makefile for 16-bit simpltst.exe 
 WSASIMPL\SIMPLT32.MAK Makefile for 32-bit simplt32.exe 
 WSASIMPL\WSASIMPL.DEF 
 WSASIMPL\WSASIMPL.H 
 WSASIMPL\WSASIMPL.RC 
 WSASIMPL\WSASIMPL.C 
 WSASIMPL\WSASIMPL.MAK Makefile for 16-bit wsasimpl.dll 
 WSASIMPL\WSASMP32.MAK Makefile for 32-bit wsasmp32.dll

--------
 NOTES:
--------

We used Microsoft Visual C++ enviroments (versions 1.52 for 16-bit,
and version 2.1 for 32-bit) to create most of the makefiles.
Unfortunately, because the paths are hard-coded in the file, you will
have to bring the project files (.mak) into the respective MS C++
environments to readjust things to the new directory, and even then
you will have to manually alter the project to access the library
files (the are in the root of the directory where you install the
samples).

All samples--including the sample DLL and static library--have a
number of other things in common:

  - They all have 32-bit versions, and all 32-bit version names
     end with "32" (16-bit versions don't have a number).
  - They use the WSAperror() function from #WINSOCKX">WINSOCKX.LIB
    to display error values and short descriptions when an unexpected
    error occurs.
  - They display error messages on any suspicious error condition.
     They don't hide errors, but report them whenever they occur. As
     we describe n a_c.htm">Appendix C: WinSock Error Reference,
     these error messages should appear only when a "user fixable
     error" occurs. If you get an error message from a sample
     application for a non user-fixable error, then this may
     indicate an anomoly in the WinSock implementation that your applications
     may need to deal with. We show you the errors on purpose, to make
     you aware of unexpected conditions.
  - They have a minimal user interface, and do not have help (.HLP)
     files available.
  - They are meant to be played with. They are for exploration
     and experimentation as well as to illustrate how to write WinSock
     applications.

The icons used for each sample don't mean much, but they meet
the following three criteria:

    - They each contain the socket from the official WinSock icon.
    - Each one is colorful in its own unique and wonderful way.
    - Each took under 10 minutes to create.
