Important: |
---|
This is retired content. This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies. This content may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist. |
This function initiates use of a Windows Sockets service provider by a client.
Syntax
int WSPStartup( WORD wVersionRequested, LPWSPDATAW lpWSPData, LPWSAPROTOCOL_INFOW lpProtocolInfo, WSPUPCALLTABLE UpcallTable, LPWSPPROC_TABLE lpProcTable ); |
Parameters
- wVersionRequested
-
[in] Highest version of Windows Sockets SPI support that the caller can use. The high-order byte specifies the minor version (revision) number; the low-order byte specifies the major version number.
- lpWSPData
-
[out] Pointer to the data structure that is to receive details of the Windows Sockets service provider.
- lpProtocolInfo
-
[in] Pointer to a WSAPROTOCOL_INFOWstructure that defines the characteristics of the desired protocol. This is especially useful when a single provider DLL is capable of instantiating multiple different service providers.
- UpcallTable
-
[in] Upcall dispatch table for ws2.dll.
- lpProcTable
-
[out] Pointer to the table of SPI function pointers.
Return Value
This function returns zero if successful. Otherwise, it returns an error code.
The following table shows the possible error codes.
Error value | Description |
---|---|
WSASYSNOTREADY |
Indicates that the underlying network subsystem is not ready for network communication. |
WSAVERNOTSUPPORTED |
Version of Windows Sockets SPI support requested is not provided by this particular Windows Sockets service provider. |
WSAEINPROGRESS |
Blocking Windows Sockets operation is in progress. |
WSAEPROCLIM |
Limit on the number of clients supported by the Windows Sockets implementation has been reached. |
WSAEFAULT |
The lpWSPDataor lpProcTableparameter is invalid. |
Remarks
This function mustbe the first Windows Sockets SPI function called by a Windows Sockets SPI client on a per-process basis. It allows the client to specify the version of Windows Sockets SPI required and to provide its upcall dispatch table. All upcalls (that is, functions prefixed with WPU) made by the Windows Sockets service provider are invoked through the client's upcall dispatch table. This function also allows the client to retrieve details of the specific Windows Sockets service provider implementation. The Windows Sockets SPI client can only issue further Windows Sockets SPI functions after a successful WSPStartupinvocation. A table of pointers to the rest of the SPI functions is retrieved through the lpProcTableparameter.
In order to support future versions of the Windows Sockets SPI and the ws2.dll, which may have functionality differences from the current Windows Sockets SPI, a negotiation takes place in WSPStartup. The caller of WSPStartup(either the ws2.dll or a layered protocol) and the Windows Sockets service provider indicate to each other the highest version that they can support, and each confirms that the other's highest version is acceptable. On entering WSPStartup, the Windows Sockets service provider examines the version requested by the client. If this version is equal to or later than the lowest version supported by the service provider, the call succeeds and the service provider returns in wHighVersionthe highest version it supports and in wVersionthe minimum of its high version and wVersionRequested.The Windows Sockets service provider then assumes that the Windows Sockets SPI client will use wVersion.If the wVersionmember of the WSPDATAstructure is unacceptable to the caller, it should call WSPCleanupand either search for another Windows Sockets service provider or fail to initialize.
This negotiation allows both a Windows Sockets service provider and a Windows Sockets SPI client to support a range of Windows Sockets versions. A client can successfully utilize a Windows Sockets service provider if there is any overlap in the version ranges.
The following table gives examples of how WSPStartupworks in conjunction with different ws2.dll and Windows Sockets service provider versions.
DLL versions | Service provider versions | wVersion requested | wVersion | wHigh version | 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 |
DLL fails |
1.0 |
1.1 |
1.0 |
--- |
--- |
WSAVERNOTSUPPORTED |
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 |
2.0 |
2.0 |
2.0 |
2.0 |
use 2.0 |
The following code sample shows how a Windows Sockets SPI client makes a WSPStartupcall.
Copy Code | |
---|---|
WORD wVersionRequested; WSPDATA WSPData; int err; WSPUPCALLTABLE upcallTable = { /* initialize upcallTable with function pointers */ }; LPWSPPROC_TABLE lpProcTable = { /* allocate memory for the ProcTable */ }; wVersionRequested = MAKEWORD( 2, 2 ); err = WSPStartup( wVersionRequested, &WSPData, lpProtocolBuffer, upcallTable, lpProcTable ); if ( err != 0 ) { /* Tell the user that we could not find a useable */ /* Windows Sockets service provider. */ return; } /* Confirm that the Windows Sockets service provider supports 2.2.*/ /* Note that if the service provider supports versions */ /* later than 2.2 in addition to 2.2, it will still */ /* return 2.2 in wVersion since that is the version we */ /* requested. */ if ( LOBYTE( WSPData.wVersion ) != 2 || HIBYTE( WSPData.wVersion ) != 2 ) { /* Tell the user that we could not find a useable */ /* Windows Sockets service provider. */ WSPCleanup( ); return; } /* The Windows Sockets service provider is acceptable. Proceed. */ |
The following code sample shows how a Windows Sockets service provider performs the WSPStartupnegotiation.
Copy Code | |
---|---|
/* Make sure that the version requested is >= 2.2. */ /* The low byte is the major version and the high */ /* byte is the minor version. */ if ( LOBYTE( wVersionRequested ) < 2) || ((LOBYTE( wVersionRequested ) == 2) && (HIBYTE( wVersionRequested ) < 2))) { return WSAVERNOTSUPPORTED; } /* Since we only support 2.2, set both wVersion and */ /* wHighVersion to 2.2. */ lpWSPData->wVersion = MAKEWORD( 2, 2 ); lpWSPData->wHighVersion = MAKEWORD( 2, 2 ); |
Once the Windows Sockets SPI client has made a successful WSPStartupcall, it can proceed to make other Windows Sockets SPI calls as needed. When it has finished using the services of the Windows Sockets service provider, the client must call WSPCleanupin order to allow the Windows Sockets service provider to free any resources allocated for the client.
A Windows Sockets SPI client can call WSPStartupmore than once if it needs to obtain the WSPDatastructure information more than once. On each such call the client can specify any version number supported by the provider.
There must be one WSPCleanupcall corresponding to every successful WSPStartupcall to allow third-party DLLs to make use of a Windows Sockets provider. This means, for example, that if WSPStartupis called three times, the corresponding call to WSPCleanupmust occur three times. The first two calls to WSPCleanupdo nothing except decrement an internal counter; the final WSPCleanupcall does all necessary resource deallocation.
This function, like most other service provider functions, can be invoked in a thread that started out as a 16-bit process if the client is a 16-bit Windows Sockets 1.1 client. One important limitation of 16-bit processes is that a 16-bit process cannot create threads. This is significant to service provider implementers that plan to use an internal service thread as part of the implementation.
The following list shows the strong conditions for a service thread:
- In the implementation of overlapped I/O completion.
- In the implementation of
WSPEventSelect.
Both of these areas are only accessible through new Windows Sockets 2 functions, which can only be invoked by 32-bit processes.
The following list shows the design rules that, if carefully followed, allow a service thread to be safely used:
- Use a service thread only for functionality that is unavailable
to 16-bit Windows Sockets 1.1 clients.
- Create the service thread only on demand.
Several other cautions apply to the use of internal service threads. First, threads generally carry some performance penalty. Use as few as possible, and avoid thread transitions wherever possible. Second, your code should always check for errors in creating threads and fail gracefully and informatively in case some execution event you did not expect results in a 16-bit process executing a code path that needs threads.
Layered Service Provider Considerations
A layered service provider supplies an implementation of this function, but it is also a client of this function when it calls WSPStartupto initialize the next layer in the provider chain. The call to the next layer's WSPStartupmay happen during the execution of this layer's WSPStartupor it may be delayed and called on demand, such as when WSPSocketis called. In any case, some special considerations apply to this function's lpProtocolInfoparameter as it is propagated down through the layers of the provider chain.
The layered provider searches the ProtocolChainof the structure referenced by lpProtocolInfoto determine its own location in the chain (by searching for the layer's own catalog entry Id) and the identity of the next element in the chain. If the next element is another layer, then, when the next layer's WSPStartupis called, this layer must pass to the next layer a lpProtocolInfothat references the same unmodified WSAPROTOCOL_INFOWstructure with the same unmodified chain information. However, if the next layer is the base protocol (that is, the last element in the chain), this layer performs a substitution when calling the base provider's WSPStartup. In this case, the base provider's WSAPROTOCOL_INFOWstructure should be referenced by the lpProtocolInfoparameter.
One vital benefit of this policy is that base service providers do not have to be aware of provider chains.
This same propagation policy applies when propagating a WSAPROTOCOL_INFOWstructure through a layered sequence of other functions such as WSPAddressToString, WSPDuplicateSocket, WSPSocket, or WSPStringToAddress.
Requirements
Header | ws2spi.h |
Library | Ws2.lib |
Windows Embedded CE | Windows CE .NET 4.0 and later |
Windows Mobile | Windows Mobile Version 5.0 and later |