Initialization

The WS2_32.DLL loads the service provider's interface DLL into the system by using the standard Windows dynamic library loading mechanisms, and initializes it by calling WSPStartup. This is usually triggered by an application calling either socket 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 the WS2_32.DLLat the time the service provider is being installed. See section Configuration and Installation for more information.

Over time, different versions may exist for the WinSock 2 DLLs, applications, and service providers. New versions may define new features, new fields to data structures and bit fields, etc. Version numbers therefore indicate how to interpret various data structures.

To allow optimal mixing and matching of different versions of applications, versions of the WS2_32.DLL itself, and versions of service providers by different vendors, the SPI provides a version negotiation mechanism for use between the WS2_32.DLL and the service providers. This version negotiation is handled by WSPStartup. Basically, the WS2_32.DLLpasses to the service provider the highest version numbers it is compatible with. 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_32.DLLor 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 SP 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 The WS2_32.DLLretrieves the service provider's dispatch table via 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 two purposes. First of all, it is more convenient for the WS2_32.DLLsince a single call can be made to discover the entire set of entry points. Secondly, this enables layered service providers formed into protocol chains to operate more efficiently.

Initializing Protocol Chains

At the time the WSAPROTOCOL_INFOW struct for a protocol chain is installed, the path to the first layered provider in the chain is also specified. When a protocol chain is initialized, the WS2_32.DLLuses this path to load the provider DLL and then invokes WSPStartup. Since WSPStartup includes a pointer to the chain's WSAPROTOCOL_INFOW struct as one of its parameters, layered providers can determine what type of chain they are being initialized into, and who the next lower layer in the chain is. 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 struct 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 struct is no longer propagated downward. Instead, the current layer must reference a WSAPROTOCOL_INFOW struct that corresponds to the protocol that the base provider should use. Thus, the base provider has no notion of being involved in a protocol 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 protocol chain. These upcalls must be made directly to the WinSock 2 DLL.