Figure 3   Winsock 2 SPI Prefixes

Function Prefix
Description
WSP (Winsock Service Provider)
Transport service provider functions
WPU (Winsock Provider Upcall)
ws2_32.dll functions called by service providers
WSC (Winsock Configuration)
ws2_32.dll functions for LSP installation programs
NSP (Namespace Provider)
Namespace provider functions


Figure 4   WSPPROC_TABLE Structure

typedef struct _WSPPROC_TABLE {
    LPWSPACCEPT                 lpWSPAccept;
    LPWSPADDRESSTOSTRING        lpWSPAddressToString;
    LPWSPASYNCSELECT            lpWSPAsyncSelect;
    LPWSPBIND                   lpWSPBind;
    LPWSPCANCELBLOCKINGCALL     lpWSPCancelBlockingCall;
    LPWSPCLEANUP                lpWSPCleanup;
    LPWSPCLOSESOCKET            lpWSPCloseSocket;
    LPWSPCONNECT                lpWSPConnect;
    LPWSPDUPLICATESOCKET        lpWSPDuplicateSocket;
    LPWSPENUMNETWORKEVENTS      lpWSPEnumNetworkEvents;
    LPWSPEVENTSELECT            lpWSPEventSelect;
    LPWSPGETOVERLAPPEDRESULT    lpWSPGetOverlappedResult;
    LPWSPGETPEERNAME            lpWSPGetPeerName;
    LPWSPGETSOCKNAME            lpWSPGetSockName;
    LPWSPGETSOCKOPT             lpWSPGetSockOpt;
    LPWSPGETQOSBYNAME           lpWSPGetQOSByName;
    LPWSPIOCTL                  lpWSPIoctl;
    LPWSPJOINLEAF               lpWSPJoinLeaf;
    LPWSPLISTEN                 lpWSPListen;
    LPWSPRECV                   lpWSPRecv;
    LPWSPRECVDISCONNECT         lpWSPRecvDisconnect;
    LPWSPRECVFROM               lpWSPRecvFrom;
    LPWSPSELECT                 lpWSPSelect;
    LPWSPSEND                   lpWSPSend;
    LPWSPSENDDISCONNECT         lpWSPSendDisconnect;
    LPWSPSENDTO                 lpWSPSendTo;
    LPWSPSETSOCKOPT             lpWSPSetSockOpt;
    LPWSPSHUTDOWN               lpWSPShutdown;
    LPWSPSOCKET                 lpWSPSocket;
    LPWSPSTRINGTOADDRESS        lpWSPStringToAddress;

} WSPPROC_TABLE, FAR * LPWSPPROC_TABLE;

Figure 5   WSPUPCALLTABLE Structure

typedef struct _WSPUPCALLTABLE {

    LPWPUCLOSEEVENT                  lpWPUCloseEvent;
    LPWPUCLOSESOCKETHANDLE           lpWPUCloseSocketHandle;
    LPWPUCREATEEVENT                 lpWPUCreateEvent;
    LPWPUCREATESOCKETHANDLE          lpWPUCreateSocketHandle;
    LPWPUFDISSET                     lpWPUFDIsSet;
    LPWPUGETPROVIDERPATH             lpWPUGetProviderPath;
    LPWPUMODIFYIFSHANDLE             lpWPUModifyIFSHandle;
    LPWPUPOSTMESSAGE                 lpWPUPostMessage;
    LPWPUQUERYBLOCKINGCALLBACK       lpWPUQueryBlockingCallback;
    LPWPUQUERYSOCKETHANDLECONTEXT    lpWPUQuerySocketHandleContext;
    LPWPUQUEUEAPC                    lpWPUQueueApc;
    LPWPURESETEVENT                  lpWPUResetEvent;
    LPWPUSETEVENT                    lpWPUSetEvent;
    LPWPUOPENCURRENTTHREAD           lpWPUOpenCurrentThread;
    LPWPUCLOSETHREAD                 lpWPUCloseThread;

} WSPUPCALLTABLE, FAR * LPWSPUPCALLTABLE;

Figure 6   Completion Semantics for an Overlapped Socket

lpOverlapped
hEvent
lpCompletionRoutine
Completion Indication
NULL
Not applicable
Ignored
Operation completes synchronously, that is it behaves as if it were a nonoverlapped socket.
!NULL
NULL
NULL
Operation completes overlapped, but there is no Winsock 2 supported completion mechanism. The completion port mechanism (if supported) may be used in this case, otherwise there will be no completion notification.
!NULL
!NULL
NULL
Operation completes overlapped; notification by signaling event object.
!NULL
Ignored
!NULL
Operation completes overlapped; notification by scheduling completion routine.


Figure 7   WSAOVERLAPPED Structure Details

typedef struct _WSAOVERLAPPED {
    DWORD        Internal;        // reserved
    DWORD        InternalHigh;    // reserved
    DWORD        Offset;          // reserved
    DWORD        OffsetHigh;      // reserved
    WSAEVENT     hEvent;
} WSAOVERLAPPED, LPWSAOVERLAPPED;
Internal
For IFS providers, this field is used by the under-lying operating system. Non-IFS providers are free to use this field as necessary.
InternalHigh
For IFS providers, this field is used by the underlying operating system. Non-IFS providers are free to use this field as necessary.
Offset
This field is reserved for service providers.
OffsetHigh
This field is reserved for service providers.
hEvent
If an overlapped I/O operation is issued without an I/O completion routine (lpCompletion-Routine is NULL), then this field must contain a valid handle to a WSAEVENT object. Otherwise (lpCompletionRoutine is non-NULL) the client is free to use this field as necessary.


Figure 8   WSAPROTOCOL_INFOW Structure

typedef struct {
    DWORD dwServiceFlags1;
    DWORD dwServiceFlags2;
    DWORD dwServiceFlags3;
    DWORD dwServiceFlags4;
    DWORD dwProviderFlags;
    GUID ProviderId;
    DWORD dwCatalogEntryId;
    WSAPROTOCOLCHAIN ProtocolChain;
    int iVersion;
    int iAddressFamily;
    int iMaxSockAddr;
    int iMinSockAddr;
    int iSocketType;
    int iProtocol;
    int iProtocolMaxOffset;
    int iNetworkByteOrder;
    int iSecurityScheme;
    DWORD dwMessageSize;
    DWORD dwProviderReserved;
    WCHAR szProtocol[WSAPROTOCOL_LEN+1];
} WSAPROTOCOL_INFOW;

Figure 9   Installing a Protocol Chain

•
•
•
WSAPROTOCOL_INFOW LayeredProtocolInfoBuff, ProtocolChainProtoInfo, BaseProtocolInfoBuff;
•
•
•
// Retrieve BaseProtocolInfoBuff using WSCEnumProtocols

Memcpy (&LayeredProtocolInfoBuff , &BaseProtocolInfoBuff, sizeof(WSAPROTOCOL_INFO));
LayeredProtocolInfoBuff.dwProviderFlags = PFL_HIDDEN;
LayeredProtocolInfoBuff.ProviderId = LayeredProviderGuid;
LayeredProtocolInfoBuff.dwCatalogEntryId = 0;   // to be filled in by system
LayeredProtocolInfoBuff.ProtocolChain.ChainLen = LAYERED_PROTOCOL;
WSCInstallProvider(
        &LayeredProviderGuid,
        L"lsp.dll",               // lpszProviderDllPath
        &LayeredProtocolInfoBuff, // lpProtocolInfoList
        1,                        // dwNumberOfEntries
        & install_error           // lpErrno
);

Memcpy(&ProtocolChainProtoInfo, &BaseProtocolInfoBuff, sizeof(WSAPROTOCOL_INFO));
ProtocolChainProtoInfo.ProtocolChain.ChainLen = 2;
ProtocolChainProtoInfo.ProtocolChain.ChainEntries[0] = LayeredProvideProtocolInfo.dwCatalogEntryId;
ProtocolChainProtoInfo.ProtocolChain.ChainEntries[1] = BaseProtocolInfoBuff.dwCatalogEntryId;

WSCInstallProvider(
        &ChainedProviderGuid,
        L"lsp.dll",              // lpszProviderDllPath
        &ProtocolChainProtoInfo, // lpProtocolInfoList
        1,                       // dwNumberOfEntries
        & install_error          // lpErrno
);

Figure 11   Layered Sample Files

Files
Contains
INSTALL.H, INST_LSP.CPP
The lsp.dll installation program.
NOWARN.H
Pragmas to turn off compiler warnings that may be safely ignored.
DLLMAIN.CPP
lsp.dll’s DllMain implementation.
PRECCOMP.H
All the headers required to build a precompiled header.
CLASSFWD.H
Definitions for the classes used in the lsp.dll.
TRACE.CPP, TRACE.H
Debug print functions.
LLIST.H
A doubly linked list and a singly linked list and their manipulation functions.
GLOBALS.H
The external definitions of the global objects.
DTHOOK.H, DTHOOK.CPP, DBGTRACE.H
ws2_32 debugging trace implementation.
DCATITEM.H , DCATITEM.CPP
The PROTO_CATALOG_ITEM object for a provider’s WSAPROTOCOL_INFOW structure.
DCATALOG.H, DCATALOG.CPP
The DCATALOG object contains a list of PROTO_CATALOG_ITEM objects for all installed providers. The FindNextProviderInChain function loads the next provider in the chain.
DASYNCW.H , DASYNCW.CPP
The DASYNCWINDOW object implements a dedicated thread in which a hidden window and message pump are created to perform the base provider asynchronous Winsock operation.
DBUFFMGR.H, DBUFFMGR.CPP
The DBUFFERMANAGER object provides no-op functions users can overwrite to intercept and modify data streams involved in Winsock I/O.
DOVERLAP.H, DOVERLAP.CPP
The INTERNALOVERLAPPEDSTRUCT structure, an extended overlapped structure containing context for an overlapped I/O. The DOVERLAPPED-STRUCTMGR object maintains a list of INTERNALOVERLAPPEDSTRUCTs and utility functions for manipulating the list.
DPROVIDE.H, DPROVIDE.CPP
The DPROVIDER object is used to store the lower chain provider. It contains all WSP functions from a lower chain provider.
DSOCKET.H, DSOCKET.CPP
The DSOCKET object links this provider socket and a lower chain socket, and contains the operation modes of the lower chain socket.
DWORKER.H , DWORKER.CPP
The DWORKERTHREAD object creates a worker thread to invoke and get completion notification of the base provider’s overlapped I/O. On Windows NT, IOCP is used; on Windows 9x a semaphore is used.
SPI.CPP
The implementation of lsp.dll’s SPI functions.