Description
#include <winsock.h>
int PASCAL FAR WSAStartup ( WORD wVersionRequired, LPWSADATA lpWSAData );
wVersionRequired
Remarks
This function must be the first Windows Sockets function called by an application or DLL. It allows an application to specify the version of Windows Sockets API required and to retrieve details of the specific Windows Sockets implementation. The application may only issue further Windows Sockets API functions after a successful WSAStartup() invocation.
In order to support future Windows Sockets implementations and applications which may have functionality differences from Windows Sockets 1.1, a negotiation takes place in WSAStartup(). The caller of WSAStartup() and the Windows Sockets DLL indicate to each other the highest version that they can support, and each confirms that the other's highest version is acceptable. Upon entry to WSAStartup(), the Windows Sockets DLL examines the version requested by the application. If this version is higher than the lowest version supported by the DLL, the call succeeds and the DLL returns in wHighVersion the highest version it supports and in wVersion the minimum of its high version and wVersionRequested. The Windows Sockets DLL then assumes that the application will use wVersion. If the wVersion field of the WSADATA structure is unacceptable to the caller, it should call WSACleanup() and either search for another Windows Sockets DLL or fail to initialize.
This negotiation allows both a Windows Sockets DLL and a Windows Sockets application to support a range of Windows Sockets versions. An application can successfully utilize a Windows Sockets DLL if there is any overlap in the version ranges. The following chart gives examples of how WSAStartup() works in conjunction with different application and Windows Sockets DLL versions:
App versions DLL Versions wVersionRequested wVersion wHighVersion End Result------------ ------------ ----------------- -------- ------------ ---------- 1.1 1.1 1.1 1.1 1.1 use 1.1 1 . 0 1 . 1 1 . 0 1 . 1 1 . 0 1 . 0 use 1 . 0 1 . 0 1 . 0 1 . 1 1 . 0 1 . 0 1 . 1 use 1 . 0 1 . 1 1 . 0 1 . 1 1 . 1 1 . 1 1 . 1 use 1 . 1 1 . 1 1 . 0 1 . 1 1 . 0 1 . 0 App fails 1 . 0 1 . 1 1 . 0 - - - - - - NotSupp 1 . 0 1 . 1 1 . 0 1 . 1 1 . 1 1 . 1 1 . 1 use 1 . 1 1 . 1 2 . 0 1 . 1 2 . 0 1 . 1 1 . 1 use 1 . 1 2 . 0 1 . 1 2 . 0 1 . 1 1 . 1 App fails
The following code fragment demonstrates how an application which supports only version 1.1 of Windows Sockets makes a WSAStartup() call:
WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD( 1, 1 ); err = WSAStartup( wVersionRequested, &wsaData ); if ( err ]= 0 ) { /* Tell the user that we couldn't find a useable */ /* winsock.dll. */ return; } /* Confirm that the Windows Sockets DLL supports 1.1.*/ /* Note that if the DLL supports versions greater */ /* than 1.1 in addition to 1.1, it will still return */ /* 1.1 in wVersion since that is the version we */ /* requested. */ if ( LOBYTE( wsaData.wVersion ) ]= 1 !! HIBYTE( wsaData.wVersion ) ]= 1 ) { /* Tell the user that we couldn't find a useable */ /* winsock.dll. */ WSACleanup( ); return; } /* The Windows Sockets DLL is acceptable. Proceed. */
And this code fragment demonstrates how a Windows Sockets DLL which supports only version 1.1 performs the WSAStartup() negotiation:
/* Make sure that the version requested is >= 1.1. */ /* The low byte is the major version and the high */ /* byte is the minor version. */ if ( LOBYTE( wVersionRequested ) < 1 !! ( LOBYTE( wVersionRequested ) == 1 && HIBYTE( wVersionRequested ) < 1 ) { return WSAVERNOTSUPPORTED; } /* Since we only support 1.1, set both wVersion and */ /* wHighVersion to 1.1. */ lpWsaData->wVersion = MAKEWORD( 1, 1 ); lpWsaData->wHighVersion = MAKEWORD( 1, 1 );
Once an application has made a successful WSAStartup() call, it may proceed to make other Windows Sockets API calls as needed. When it has finished using the services of the Windows Sockets DLL, the application must call WSACleanup() in order to allow the DLL to free any resources allocated by the Windows Sockets DLL for the application. Details of the actual Windows Sockets implementation are described in the WSAData structure defined as follows:
struct WSAData { WORD wVersion; WORD wHighVersion; char szDescriptionφWSADESCRIPTION_LEN+1∙; char szSystemStatusφWSASYSSTATUS_LEN+1∙; unsigned short iMaxSockets; unsigned short iMaxUdpDg; char FAR * lpVendorInfo };
The members of this structure are:
wVersion
An application may call WSAStartup() more than once if it needs to obtain the WSAData structure information more than once. However, the wVersionRequired parameter is assumed to be the same on all calls to WSAStartup(); that is, an application cannot change the version of Windows Sockets it expects after the initial call to WSAStartup().
There must be one WSACleanup() call corresponding to every WSAStartup() call to allow third-party DLLs to make use of a Windows Sockets DLL on behalf of an application. This means, for example, that if an application calls WSAStartup() three times, it must call WSACleanup() three times. The first two calls to WSACleanup() do nothing except decrement an internal counter; the final WSACleanup() call does all necessary resource deallocation for the task.
Return Value
WSAStartup() returns zero if successful. Otherwise it returns one of the error codes listed below. Note that the normal mechanism whereby the application calls WSAGetLastError() to determine the error code cannot be used, since the Windows Sockets DLL may not have established the client data area where the "last error" information is stored.
Notes For Windows Sockets Suppliers
Each Windows Sockets application must make a WSAStartup() call before issuing any other Windows Sockets API calls. This function can thus be utilized for initialization purposes.
Further issues are discussed in the notes for WSACleanup().
Error Codes
WSASYSNOTREADY
See Also
send(), sendto(), WSACleanup()