Service Provider Activation
A version of this page is also available for
4/8/2010
Ws2.dll loads the service provider's interface DLL into the system by using the standard Microsoft Windows dynamic library loading mechanisms, and initializes it by calling WSPStartup. This is usually triggered by an application calling either socket (Windows Sockets) or WSASocket in order to create a new socket that is to be associated with a service provider whose interface DLL is not currently loaded into memory. The path to each service provider's interface DLL is stored by Ws2.dll at the time the service provider is being installed.
Over time, different versions may exist for the Winsock DLLs, applications, and service providers. New versions may define new functionality, new parameters to data structures and bit parameters, and so on. Version numbers therefore indicate how to interpret various data structures.
To allow optimal mixing and matching of different versions of applications, versions of Ws2.dll itself, and versions of service providers by different vendors, the SPI provides a version negotiation mechanism for use between Ws2.dll and the service providers. This version negotiation is handled by WSPStartup. Basically, Ws2.dll passes to the service provider the highest version numbers with which it is compatible. The service provider compares this with its own supported range of version numbers. If these ranges overlap, the service provider returns a value within the overlapping portion of the range as the result of the negotiation. Usually, this should be the highest possible value. If the ranges do not overlap, the two parties are incompatible and the function returns an error.
WSPStartup must be called at least once by each client process, and may be called multiple times by Ws2.dll or other entities. A matching WSPCleanup must be called for each successful WSPStartup call. The service provider should maintain a reference count on a per-process basis. On each WSPStartup call, the caller may specify any version number supported by the service provider DLL.
A service provider must store the pointer to the client's upcall dispatch table that is received as a WSPStartup parameter on a per-process basis. If a given process calls WSPStartup multiple times, the service provider must use only the most recently supplied dispatch table pointer.
As part of the service provider initialization process, Ws2.dll retrieves the service provider's dispatch table through the lpProcTable parameter in order to obtain entry points to the rest of the SPI functions specified in this document.
Using a dispatch table, as opposed to the usual DLL mechanisms for accessing entry points, serves the following two purposes:
- It is more convenient for Ws2.dll because a single call can be made to discover the entire set of entry points.
- It enables layered service providers formed into provider chains to operate more efficiently.
Initializing Provider Chains
At the time the WSAPROTOCOL_INFOW structure for a provider chain is installed, the path to the first layered provider in the chain is also specified. When a provider chain is initialized, Ws2.dll uses this path to load the provider DLL and then invokes WSPStartup. Because WSPStartup includes a pointer to the chain's WSAPROTOCOL_INFOW structure as one of its parameters, layered providers can determine what type of provider chain they are being initialized into, and the identity of the next lower layer in the chain. A layered provider would then in turn load the next protocol provider in the chain and initialize it with a call to WSPStartup, and so forth. Whenever the next lower layer is another layered provider, the chain's WSAPROTOCOL_INFOW structure must be referenced in the WSPStartup call. When the next lower layer is a base protocol (signifying the end of the chain), the chain's WSAPROTOCOL_INFOW structure is no longer propagated downward. Instead, the current layer must reference a WSAPROTOCOL_INFOW structure that corresponds to the protocol that the base provider should use. Thus, the base provider has no notion of being involved in a provider chain.
The dispatch table provided by any given layered provider will, in many instances, duplicate the entry points of an underlying provider. The layered provider would only insert its own entry points for functions that it needed to be directly involved in. Note, however, that it is imperative that a layered provider not modify the contents of the upcall table that it received when calling WSPStartup on the next lower layer in a provider chain. These upcalls must be made directly to the Winsock DLL.