mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
4195 lines
182 KiB
4195 lines
182 KiB
|
|
SOCKET
|
|
WSPAPI
|
|
WSPAccept(
|
|
IN SOCKET s,
|
|
OUT struct sockaddr FAR * addr,
|
|
IN OUT LPINT addrlen,
|
|
IN LPCONDITIONPROC lpfnCondition,
|
|
IN DWORD dwCallbackData,
|
|
OUT LPINT lpErrno
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine extracts the first connection on the queue of pending
|
|
connections on s, and checks it against the condition function, provided
|
|
the condition function is specified (i.e., not NULL). The condition
|
|
function must be executed in the same thread as this routine is. If the
|
|
condition function returns CF_ACCEPT, this routine creates a new socket
|
|
and performs any socket grouping as indicated by the result parameter g
|
|
in the condition function . Newly created sockets have the same
|
|
properties as s including network events registered with WSPAsyncSelect()
|
|
or with WSPEventSelect(), but not including the listening socket's group
|
|
ID, if any.
|
|
|
|
If the condition function returns CF_REJECT, this routine rejects the
|
|
connection request. If the client's accept/reject decision cannot be made
|
|
immediately, the condition function will return CF_DEFER to indicate that
|
|
no decision has been made, and no action about this connection request is
|
|
to be taken by the service provider. When the client is ready to take
|
|
action on the connection request, it will invoke WSPAccept() again and
|
|
return either CF_ACCEPT or CF_REJECT as a return value from the condition
|
|
function.
|
|
|
|
For sockets which are in the (default) blocking mode, if no pending
|
|
connections are present on the queue, WSPAccept() blocks the caller until
|
|
a connection is present. For sockets in a non-blocking mode, if this
|
|
function is called when no pending connections are present on the queue,
|
|
WSPAccept() returns the error code WSAEWOULDBLOCK as described below. The
|
|
accepted socket may not be used to accept more connections. The original
|
|
socket remains open.
|
|
|
|
The argument addr is a result parameter that is filled in with the address
|
|
of the connecting entity, as known to the service provider. The exact
|
|
format of the addr parameter is determined by the address family in which
|
|
the communication is occurring. The addrlen is a value-result parameter;
|
|
it will initially contain the amount of space pointed to by addr. On
|
|
return, it must contain the actual length (in bytes) of the address
|
|
returned by the service provider. This call is used with connection-
|
|
oriented socket types such as SOCK_STREAM. If addr and/or addrlen are
|
|
equal to NULL, then no information about the remote address of the
|
|
accepted socket is returned. Otherwise, these two parameters shall be
|
|
filled in regardless of whether the condition function is specified or
|
|
what it returns.
|
|
|
|
The prototype of the condition function is as follows:
|
|
|
|
int
|
|
CALLBACK
|
|
ConditionFunc(
|
|
IN LPWSABUF lpCallerId,
|
|
IN LPWSABUF lpCallerData,
|
|
IN OUT LPQOS lpSQOS,
|
|
IN OUT LPQOS lpGQOS,
|
|
IN LPWSABUF lpCalleeId,
|
|
IN LPWSABUF lpCalleeData,
|
|
OUT GROUP FAR * g,
|
|
IN DWORD dwCallbackData
|
|
);
|
|
|
|
The lpCallerId and lpCallerData are value parameters which must
|
|
contain the address of the connecting entity and any user data
|
|
that was sent along with the connection request, respectively.
|
|
If no caller ID or caller data is available, the corresponding
|
|
parameter will be NULL.
|
|
|
|
lpSQOS references the flow specs for socket s specified by the
|
|
caller, one for each direction, followed by any additional
|
|
provider-specific parameters. The sending or receiving flow spec
|
|
values will be ignored as appropriate for any unidirectional
|
|
sockets. A NULL value for lpSQOS indicates no caller supplied
|
|
QOS. QOS information may be returned if a QOS negotiation is to
|
|
occur.
|
|
|
|
lpGQOS references the flow specs for the socket group the caller
|
|
is to create, one for each direction, followed by any additional
|
|
provider-specific parameters. A NULL value for lpGQOS indicates
|
|
no caller-supplied group QOS. QOS information may be returned if
|
|
a QOS negotiation is to occur.
|
|
|
|
The lpCalleeId is a value parameter which contains the local
|
|
address of the connected entity. The lpCalleeData is a result
|
|
parameter used by the condition function to supply user data back
|
|
to the connecting entity. The storage for this data must be
|
|
provided by the service provider. lpCalleeData->len initially
|
|
contains the length of the buffer allocated by the service
|
|
provider and pointed to by lpCalleeData->buf. A value of zero
|
|
means passing user data back to the caller is not supported. The
|
|
condition function will copy up to lpCalleeData->len bytes of
|
|
data into lpCalleeData->buf , and then update lpCalleeData->len
|
|
to indicate the actual number of bytes transferred. If no user
|
|
data is to be passed back to the caller, the condition function
|
|
will set lpCalleeData->len to zero. The format of all address and
|
|
user data is specific to the address family to which the socket
|
|
belongs.
|
|
|
|
The result parameter g is assigned within the condition function
|
|
to indicate the following actions:
|
|
|
|
if &g is an existing socket group ID, add s to this
|
|
group, provided all the requirements set by this group
|
|
are met; or
|
|
|
|
if &g = SG_UNCONSTRAINED_GROUP, create an unconstrained
|
|
socket group and have s as the first member; or
|
|
|
|
if &g = SG_CONSTRAINED_GROUP, create a constrained
|
|
socket group and have s as the first member; or
|
|
|
|
if &g = zero, no group operation is performed.
|
|
|
|
Any set of sockets grouped together must be implemented by a
|
|
single service provider. For unconstrained groups, any set of
|
|
sockets may be grouped together. A constrained socket group may
|
|
consist only of connection-oriented sockets, and requires that
|
|
connections on all grouped sockets be to the same address on the
|
|
same host. For newly created socket groups, the new group ID
|
|
must be available for the WinSock SPI client to retrieve by
|
|
calling WSPGetSockOpt() with option SO_GROUP_ID. A socket group
|
|
and its associated ID remain valid until the last socket
|
|
belonging to this socket group is closed. Socket group IDs are
|
|
unique across all processes for a given service provider.
|
|
|
|
dwCallbackData is supplied to the condition function exactly as
|
|
supplied by the caller of WSPAccept().
|
|
|
|
Arguments:
|
|
|
|
s - A descriptor identifying a socket which is listening for connections
|
|
after a WSPListen().
|
|
|
|
addr - An optional pointer to a buffer which receives the address of the
|
|
connecting entity, as known to the service provider. The exact
|
|
format of the addr argument is determined by the address family
|
|
established when the socket was created.
|
|
|
|
addrlen - An optional pointer to an integer which contains the length of
|
|
the address addr.
|
|
|
|
lpfnCondition - The procedure instance address of an optional, WinSock 2
|
|
client- supplied condition function which will make an accept/reject
|
|
decision based on the caller information passed in as parameters,
|
|
and optionally create and/or join a socket group by assigning an
|
|
appropriate value to the result parameter, g, of this routine.
|
|
|
|
dwCallbackData - Callback data to be passed back to the WinSock 2 client
|
|
as a condition function parameter. This parameter is not interpreted
|
|
by the service provider.
|
|
|
|
lpErrno - A pointer to the error code.
|
|
|
|
Return Value:
|
|
|
|
If no error occurs, WSPAccept() returns a value of type SOCKET which is
|
|
a descriptor for the accepted socket. Otherwise, a value of
|
|
INVALID_SOCKET is returned, and a specific error code is available
|
|
in lpErrno.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
} // WSPAccept
|
|
|
|
|
|
INT
|
|
WSPAPI
|
|
WSPAddressToString(
|
|
IN LPSOCKADDR lpsaAddress,
|
|
IN DWORD dwAddressLength,
|
|
IN LPWSAPROTOCOL_INFOW lpProtocolInfo,
|
|
OUT LPWSTR lpszAddressString,
|
|
IN OUT LPDWORD lpdwAddressStringLength,
|
|
OUT LPINT lpErrno
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine converts all components of a SOCKADDR structure into a human-
|
|
readable string representation of the address. This is used mainly for
|
|
display purposes.
|
|
|
|
Arguments:
|
|
|
|
lpsaAddress - Points to a SOCKADDR structure to translate into a string.
|
|
|
|
dwAddressLength - The length of the Address SOCKADDR.
|
|
|
|
lpProtocolInfo - The WSAPROTOCOL_INFOW struct for a particular provider.
|
|
|
|
lpszAddressString - A buffer which receives the human-readable address
|
|
string.
|
|
|
|
lpdwAddressStringLength - The length of the AddressString buffer. Returns
|
|
the length of the string actually copied into the buffer.
|
|
|
|
lpErrno - A pointer to the error code.
|
|
|
|
Return Value:
|
|
|
|
If no error occurs, WSPAddressToString() returns 0. Otherwise, it returns
|
|
SOCKET_ERROR, and a specific error code is available in lpErrno.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
} // WSPAddressToString
|
|
|
|
|
|
INT
|
|
WSPAPI
|
|
WSPAsyncSelect(
|
|
IN SOCKET s,
|
|
IN HWND hWnd,
|
|
IN unsigned int wMsg,
|
|
IN long lEvent,
|
|
OUT LPINT lpErrno
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is used to request that the service provider send a Window
|
|
message to the client's window hWnd whenever it detects any of the
|
|
network events specified by the lEvent parameter. The service provider
|
|
should use the WPUPostMessage() function to post the message. The message
|
|
to be sent is specified by the wMsg parameter. The socket for which
|
|
notification is required is identified by s.
|
|
|
|
This routine automatically sets socket s to non-blocking mode, regardless
|
|
of the value of lEvent. See WSPIoctl() about how to set the socket back to
|
|
blocking mode.
|
|
|
|
The lEvent parameter is constructed by or'ing any of the values specified
|
|
in the following list.
|
|
|
|
Value Meaning
|
|
~~~~~ ~~~~~~~
|
|
FD_READ Issue notification of readiness for reading.
|
|
FD_WRITE Issue notification of readiness for writing.
|
|
FD_OOB Issue notification of the arrival of out-of-band data.
|
|
FD_ACCEPT Issue notification of incoming connections.
|
|
FD_CONNECT Issue notification of completed connection.
|
|
FD_CLOSE Issue notification of socket closure.
|
|
FD_QOS Issue notification of socket Quality of Service (QOS)
|
|
changes.
|
|
FD_GROUP_QOS Issue notification of socket group Quality of Service
|
|
(QOS) changes.
|
|
|
|
Invoking WSPAsyncSelect() for a socket cancels any previous
|
|
WSPAsyncSelect() or WSPEventSelect() for the same socket. For example,
|
|
to receive notification for both reading and writing, the WinSock SPI
|
|
client must call WSPAsyncSelect() with both FD_READ and FD_WRITE, as
|
|
follows:
|
|
|
|
rc = WSPAsyncSelect(s, hWnd, wMsg, FD_READ | FD_WRITE, &error);
|
|
|
|
It is not possible to specify different messages for different events. The
|
|
following code will not work; the second call will cancel the effects of
|
|
the first, and only FD_WRITE events will be reported with message wMsg2:
|
|
|
|
rc = WSPAsyncSelect(s, hWnd, wMsg1, FD_READ, &error);
|
|
rc = WSPAsyncSelect(s, hWnd, wMsg2, FD_WRITE, &error); // bad
|
|
|
|
To cancel all notification - i.e., to indicate that the service provider
|
|
should send no further messages related to network events on the socket -
|
|
lEvent will be set to zero.
|
|
|
|
rc = WSPAsyncSelect(s, hWnd, 0, 0, &error);
|
|
|
|
Since a WSPAccept()'ed socket has the same properties as the listening
|
|
socket used to accept it, any WSPAsyncSelect() events set for the
|
|
listening socket apply to the accepted socket. For example, if a listening
|
|
socket has WSPAsyncSelect() events FD_ACCEPT, FD_READ, and FD_WRITE, then
|
|
any socket accepted on that listening socket will also have FD_ACCEPT,
|
|
FD_READ, and FD_WRITE events with the same wMsg value used for messages.
|
|
If a different wMsg or events are desired, the WinSock SPI client must
|
|
call WSPAsyncSelect(), passing the accepted socket and the desired new
|
|
information.
|
|
|
|
When one of the nominated network events occurs on the specified socket s,
|
|
the service provider uses WPUPostMessage() to send message wMsg to the
|
|
WinSock SPI client's window hWnd. The wParam argument identifies the
|
|
socket on which a network event has occurred. The low word of lParam
|
|
specifies the network event that has occurred. The high word of lParam
|
|
contains any error code. The error code be any error as defined in
|
|
ws2spi.h.
|
|
|
|
The possible network event codes which may be indicated are as follows:
|
|
|
|
Value Meaning
|
|
~~~~~ ~~~~~~~
|
|
FD_READ Socket s ready for reading.
|
|
FD_WRITE Socket s ready for writing.
|
|
FD_OOB Out-of-band data ready for reading on socket s.
|
|
FD_ACCEPT Socket s ready for accepting a new incoming
|
|
connection.
|
|
FD_CONNECT Connection initiated on socket s completed.
|
|
FD_CLOSE Connection identified by socket s has been closed.
|
|
FD_QOS Quality of Service associated with socket s has
|
|
changed.
|
|
FD_GROUP_QOS Quality of Service associated with the socket group
|
|
to which s belongs has changed.
|
|
|
|
Although WSPAsyncSelect() can be called with interest in multiple events,
|
|
the service provider issues the same Windows message for each event.
|
|
|
|
A WinSock 2 provider shall not continually flood a WinSock SPI client
|
|
with messages for a particular network event. Having successfully posted
|
|
notification of a particular event to a WinSock SPI client window, no
|
|
further message(s) for that network event will be posted to the WinSock
|
|
SPI client window until the WinSock SPI client makes the function call
|
|
which implicitly reenables notification of that network event.
|
|
|
|
Event Re-enabling functions
|
|
~~~~~ ~~~~~~~~~~~~~~~~~~~~~
|
|
FD_READ WSPRecv() or WSPRecvFrom().
|
|
FD_WRITE WSPSend() or WSPSendTo().
|
|
FD_OOB WSPRecv() or WSPRecvFrom().
|
|
FD_ACCEPT WSPAccept() unless the error code returned is
|
|
WSATRY_AGAIN indicating that the condition
|
|
function returned CF_DEFER.
|
|
FD_CONNECT NONE
|
|
FD_CLOSE NONE
|
|
FD_QOS WSPIoctl() with SIO_GET_QOS
|
|
FD_GROUP_QOS WSPIoctl() with SIO_GET_GROUP_QOS
|
|
|
|
Any call to the reenabling routine, even one which fails, results in
|
|
reenabling of message posting for the relevant event.
|
|
|
|
For FD_READ, FD_OOB, and FD_ACCEPT events, message posting is "level-
|
|
triggered." This means that if the reenabling routine is called and the
|
|
relevant condition is still met after the call, a WSPAsyncSelect()
|
|
message is posted to the WinSock SPI client.
|
|
|
|
The FD_QOS and FD_GROUP_QOS events are considered edge triggered. A
|
|
message will be posted exactly once when a QOS change occurs. Further
|
|
messages will not be forthcoming until either the provider detects a
|
|
further change in QOS or the WinSock SPI client renegotiates the QOS
|
|
for the socket.
|
|
|
|
If any event has already happened when the WinSock SPI client calls
|
|
WSPAsyncSelect() or when the reenabling function is called, then a
|
|
message is posted as appropriate. For example, consider the following
|
|
sequence:
|
|
|
|
1. A WinSock SPI client calls WSPListen().
|
|
2. A connect request is received but not yet accepted.
|
|
3. The WinSock SPI client calls WSPAsyncSelect() specifying
|
|
that it wants to receive FD_ACCEPT messages for the socket.
|
|
Due to the persistence of events, the WinSock service provider
|
|
posts an FD_ACCEPT message immediately.
|
|
|
|
The FD_WRITE event is handled slightly differently. An FD_WRITE message
|
|
is posted when a socket is first connected with WSPConnect() (after
|
|
FD_CONNECT, if also registered) or accepted with WSPAccept(), and then
|
|
after a WSPSend() or WSPSendTo() fails with WSAEWOULDBLOCK and buffer
|
|
space becomes available. Therefore, a WinSock SPI client can assume that
|
|
sends are possible starting from the first FD_WRITE message and lasting
|
|
until a send returns WSAEWOULDBLOCK. After such a failure the WinSock SPI
|
|
client will be notified that sends are again possible with an FD_WRITE
|
|
message.
|
|
|
|
The FD_OOB event is used only when a socket is configured to receive
|
|
out-of-band data separately. If the socket is configured to receive
|
|
out-of-band data in-line, the out-of-band (expedited) data is treated as
|
|
normal data and the WinSock SPI client must register an interest in
|
|
FD_READ events, not FD_OOB events.
|
|
|
|
The error code in an FD_CLOSE message indicates whether the socket close
|
|
was graceful or abortive. If the error code is 0, then the close was
|
|
graceful; if the error code is WSAECONNRESET, then the socket's virtual
|
|
circuit was reset. This only applies to connection-oriented sockets such
|
|
as SOCK_STREAM.
|
|
|
|
The FD_CLOSE message is posted when a close indication is received for
|
|
the virtual circuit corresponding to the socket. In TCP terms, this means
|
|
that the FD_CLOSE is posted when the connection goes into the TIME WAIT
|
|
or CLOSE WAIT states. This results from the remote end performing a
|
|
WSPShutdown() on the send side or a WSPCloseSocket(). FD_CLOSE shall only
|
|
be posted after all data is read from a socket.
|
|
|
|
In the case of a graceful close, the service provider shall only send an
|
|
FD_CLOSE message to indicate virtual circuit closure after all the
|
|
received data has been read. It shall NOT send an FD_READ message to
|
|
indicate this condition.
|
|
|
|
The FD_QOS or FD_GROUP_QOS message is posted when any field in the flow
|
|
spec associated with socket s or the socket group that s belongs to has
|
|
changed, respectively. The service provider must update the QOS
|
|
information available to the client via WSPIoctl() with SIO_GET_QOS
|
|
and/or SIO_GET_GROUP_QOS.
|
|
|
|
Here is a summary of events and conditions for each asynchronous
|
|
notification message:
|
|
|
|
FD_READ
|
|
~~~~~~~
|
|
1. When WSPAsyncSelect() called, if there is data currently
|
|
available to receive.
|
|
2. When data arrives, if FD_READ not already posted.
|
|
3. after WSPRecv() or WSPRecvfrom() called (with or without
|
|
MSG_PEEK), if data is still available to receive.
|
|
|
|
N.B. When WSPSetSockOpt() SO_OOBINLINE is enabled "data" includes
|
|
both normal data and out-of-band (OOB) data in the instances noted
|
|
above.
|
|
|
|
FD_WRITE
|
|
~~~~~~~~
|
|
1. When WSPAsyncSelect() called, if a WSPSend() or WSPSendTo() is
|
|
possible.
|
|
2. After WSPConnect() or WSPAccept() called, when connection
|
|
established.
|
|
3. After WSPSend() or WSPSendTo() fail with WSAEWOULDBLOCK, when
|
|
WSPSend() or WSPSendTo() are likely to succeed.
|
|
4. After WSPBind() on a datagram socket.
|
|
|
|
FD_OOB
|
|
~~~~~~
|
|
Only valid when WSPSetSockOpt() SO_OOBINLINE is disabled (default).
|
|
1. When WSPAsyncSelect() called, if there is OOB data currently
|
|
available to receive with the MSG_OOB flag.
|
|
2. When OOB data arrives, if FD_OOB not already posted.
|
|
3. After WSPRecv() or WSPRecvfrom() called with or without MSG_OOB
|
|
flag, if OOB data is still available to receive.
|
|
|
|
FD_ACCEPT
|
|
~~~~~~~~~
|
|
1. When WSPAsyncSelect() called, if there is currently a connection
|
|
request available to accept.
|
|
2. When a connection request arrives, if FD_ACCEPT not already
|
|
posted.
|
|
3. After WSPAccept() called, if there is another connection request
|
|
available to accept.
|
|
|
|
FD_CONNECT
|
|
~~~~~~~~~~
|
|
1. When WSPAsyncSelect() called, if there is currently a connection
|
|
established.
|
|
2. After WSPConnect() called, when connection is established (even
|
|
when WSPConnect() succeeds immediately, as is typical with a
|
|
datagram socket)
|
|
|
|
FD_CLOSE
|
|
~~~~~~~~
|
|
Only valid on connection-oriented sockets (e.g. SOCK_STREAM)
|
|
1. When WSPAsyncSelect() called, if socket connection has been
|
|
closed.
|
|
2. After remote system initiated graceful close, when no data
|
|
currently available to receive (note: if data has been received
|
|
and is waiting to be read when the remote system initiates a
|
|
graceful close, the FD_CLOSE is not delivered until all pending
|
|
data has been read).
|
|
3. After local system initiates graceful close with WSPShutdown()
|
|
and remote system has responded with "End of Data" notification
|
|
(e.g. TCP FIN), when no data currently available to receive.
|
|
4. When remote system aborts connection (e.g. sent TCP RST), and
|
|
lParam will contain WSAECONNRESET error value.
|
|
|
|
N.B. FD_CLOSE is not posted after WSPClosesocket() is called.
|
|
|
|
FD_QOS
|
|
~~~~~~
|
|
1. When WSPAsyncSelect() called, if the QOS associated with the
|
|
socket has been changed.
|
|
2. After WSPIoctl() with SIO_GET_QOS called, when the QOS is
|
|
changed.
|
|
|
|
FD_GROUP_QOS
|
|
~~~~~~~~~~~~
|
|
1. When WSPAsyncSelect() called, if the group QOS associated with
|
|
the socket has been changed.
|
|
2. After WSPIoctl() with SIO_GET_GROUP_QOS called, when the group
|
|
QOS is changed.
|
|
|
|
Arguments:
|
|
|
|
s - A descriptor identifying the socket for which event notification is
|
|
required.
|
|
|
|
hWnd - A handle identifying the window which should receive a message
|
|
when a network event occurs.
|
|
|
|
wMsg - The message to be sent when a network event occurs.
|
|
|
|
lEvent - A bitmask which specifies a combination of network events in
|
|
which the WinSock SPI client is interested.
|
|
|
|
lpErrno - A pointer to the error code.
|
|
|
|
Return Value:
|
|
|
|
The return value is 0 if the WinSock SPI client's declaration of
|
|
interest in the network event set was successful. Otherwise the
|
|
value SOCKET_ERROR is returned, and a specific error code is
|
|
available in lpErrno.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
} // WSPAsyncSelect
|
|
|
|
|
|
INT
|
|
WSPAPI
|
|
WSPBind(
|
|
IN SOCKET s,
|
|
IN const struct sockaddr FAR * name,
|
|
IN int namelen,
|
|
OUT LPINT lpErrno
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is used on an unconnected connectionless or connection-
|
|
oriented socket, before subsequent WSPConnect()s or WSPListen()s. When
|
|
a socket is created with WSPSocket(), it exists in a name space (address
|
|
family), but it has no name or local address assigned. WSPBind()
|
|
establishes the local association of the socket by assigning a local
|
|
name to an unnamed socket.
|
|
|
|
As an example, in the Internet address family, a name consists of three
|
|
parts: the address family, a host address, and a port number which
|
|
identifies the WinSock SPI client. In WinSock 2, the name parameter is
|
|
not strictly interpreted as a pointer to a "sockaddr" struct. Service
|
|
providers are free to regard it as a pointer to a block of memory of size
|
|
namelen. The first two bytes in this block (corresponding to "sa_family"
|
|
in the "sockaddr" declaration) must contain the address family that was
|
|
used to create the socket. Otherwise the error WSAEFAULT shall be
|
|
indicated.
|
|
|
|
If a WinSock 2 SPI client does not care what local address is assigned to
|
|
it, it will specify the manifest constant value ADDR_ANY for the sa_data
|
|
field of the name parameter. This instructs the service provider to use
|
|
any appropriate network address. For TCP/IP, if the port is specified
|
|
as 0, the service provider will assign a unique port to the WinSock SPI
|
|
client with a value between 1024 and 5000. The SPI client may use
|
|
WSPGetSockName() after WSPBind() to learn the address and the port that
|
|
has been assigned to it, but note that if the Internet address is equal
|
|
to INADDR_ANY, WSPGetSockOpt() will not necessarily be able to supply the
|
|
address until the socket is connected, since several addresses may be
|
|
valid if the host is multi-homed.
|
|
|
|
Arguments:
|
|
|
|
s - A descriptor identifying an unbound socket.
|
|
|
|
name - The address to assign to the socket. The sockaddr structure is
|
|
defined as follows:
|
|
|
|
struct sockaddr {
|
|
u_short sa_family;
|
|
char sa_data[14];
|
|
};
|
|
|
|
Except for the sa_family field, sockaddr contents are expressed in
|
|
network byte order.
|
|
|
|
namelen - The length of the name.
|
|
|
|
lpErrno - A pointer to the error code.
|
|
|
|
Return Value:
|
|
|
|
If no error occurs, WSPBind() returns 0. Otherwise, it returns
|
|
SOCKET_ERROR, and a specific error code is available in lpErrno.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
} // WSPBind
|
|
|
|
|
|
INT
|
|
WSPAPI
|
|
WSPCancelBlockingCall(
|
|
OUT LPINT lpErrno
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine cancels any outstanding blocking operation for this thread.
|
|
It is normally used in two situations:
|
|
|
|
1. A WinSock SPI client is processing a message which has been
|
|
received while a service provider is implementing pseudo
|
|
blocking. In this case, WSAIsBlocking() will be true.
|
|
|
|
2. A blocking call is in progress, and the WinSock service
|
|
provider has called back to the WinSock SPI client's "blocking
|
|
hook" function (via the callback function retrieved from
|
|
WPUQueryBlockingCallback()), which in turn is invoking this
|
|
function. Such a situation might arise, for instance, in
|
|
implementing a Cancel option for an operation which require an
|
|
extended time to complete.
|
|
|
|
In each case, the original blocking call will terminate as soon as
|
|
possible with the error WSAEINTR. (In (1), the termination will not take
|
|
place until Windows message scheduling has caused control to revert back
|
|
to the pseudo blocking routine in WinSock. In (2), the blocking call
|
|
will be terminated as soon as the blocking hook function completes.)
|
|
|
|
In the case of a blocking WSPConnect() operation, WinSock will terminate
|
|
the blocking call as soon as possible, but it may not be possible for
|
|
the socket resources to be released until the connection has completed
|
|
(and then been reset) or timed out. This is likely to be noticeable only
|
|
if the WinSock SPI client immediately tries to open a new socket (if no
|
|
sockets are available), or to WSPConnect() to the same peer.
|
|
|
|
Canceling an WSPAccept() or a WSPSelect() call does not adversely impact
|
|
the sockets passed to these calls. Only the particular call fails; any
|
|
operation that was legal before the cancel is legal after the cancel,
|
|
and the state of the socket is not affected in any way.
|
|
|
|
Canceling any operation other than WSPAccept() and WSPSelect() can leave
|
|
the socket in an indeterminate state. If a WinSock SPI client cancels a
|
|
blocking operation on a socket, the only operation that the WinSock SPI
|
|
client can depend on being able to perform on the socket is a call to
|
|
WSPCloseSocket(), although other operations may work on some WinSock
|
|
service providers. If a WinSock SPI client desires maximum portability,
|
|
it must be careful not to depend on performing operations after a cancel.
|
|
A WinSock SPI client may reset the connection by setting the timeout on
|
|
SO_LINGER to 0 and calling WSPCloseSocket().
|
|
|
|
If a cancel operation compromised the integrity of a SOCK_STREAM's data
|
|
stream in any way, the WinSock provider will reset the connection and
|
|
fail all future operations other than WSPCloseSocket() with
|
|
WSAECONNABORTED.
|
|
|
|
Note it is acceptable for WSPCancelBlockingCall() to return successfully
|
|
if the blocking network operation completes prior to being canceled. In
|
|
this case, the blocking operation will return successfully as if
|
|
WSPCancelBlockingCall() had never been called. The only way for the
|
|
WinSock SPI client to know with certainty that an operation was actually
|
|
canceled is to check for a return code of WSAEINTR from the blocking call.
|
|
|
|
Arguments:
|
|
|
|
lpErrno - A pointer to the error code.
|
|
|
|
Return Value:
|
|
|
|
The value returned by WSPCancelBlockingCall() is 0 if the operation was
|
|
successfully canceled. Otherwise the value SOCKET_ERROR is returned,
|
|
and a specific error code is available in lpErrno.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
} // WSPCancelBlockingCall
|
|
|
|
|
|
INT
|
|
WSPAPI
|
|
WSPCleanup(
|
|
OUT LPINT lpErrno
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
The WinSock 2 SPI client is required to perform a successful WSPStartup()
|
|
call before it can use WinSock service providers. When it has completed
|
|
the use of WinSock service providers, the SPI client will call
|
|
WSPCleanup() to deregister itself from a WinSock service provider and
|
|
allow the service provider to free any resources allocated on behalf of
|
|
the WinSock 2 client. It is permissible for SPI clients to make more than
|
|
one WSPStartup() call. For each WSPStartup() call a corresponding
|
|
WSPCleanup() call will also be issued. Only the final WSPCleanup() for
|
|
the service provider does the actual cleanup; the preceding calls simply
|
|
decrement an internal reference count in the WinSock service provider.
|
|
|
|
When the internal reference count reaches zero and actual cleanup
|
|
operations commence, any pending blocking or asynchronous calls issued by
|
|
any thread in this process are canceled without posting any notification
|
|
messages or signaling any event objects. Any pending overlapped send and
|
|
receive operations (WSPSend()/WSPSendTo()/WSPRecv()/WSPRecvFrom() with an
|
|
overlapped socket) issued by any thread in this process are also canceled
|
|
without setting the event object or invoking the completion routine, if
|
|
specified. In this case, the pending overlapped operations fail with the
|
|
error status WSA_OPERATION_ABORTED. Any sockets open when WSPCleanup() is
|
|
called are reset and automatically deallocated as if WSPClosesocket() was
|
|
called; sockets which have been closed with WSPCloseSocket() but which
|
|
still have pending data to be sent are not affected--the pending data is
|
|
still sent.
|
|
|
|
This routine should not return until the service provider DLL is
|
|
prepared to be unloaded from memory. In particular, any data remaining
|
|
to be transmitted must either already have been sent or be queued for
|
|
transmission by portions of the transport stack that will not be unloaded
|
|
from memory along with the service provider's DLL.
|
|
|
|
A WinSock service provider must be prepared to deal with a process which
|
|
terminates without invoking WSPCleanup() - for example, as a result of an
|
|
error. A WinSock service provider must ensure that WSPCleanup() leaves
|
|
things in a state in which the WinSock 2 DLL can immediately invoke
|
|
WSPStartup() to re-establish WinSock usage.
|
|
|
|
Arguments:
|
|
|
|
lpErrno - A pointer to the error code.
|
|
|
|
Return Value:
|
|
|
|
The return value is 0 if the operation has been successfully initiated.
|
|
Otherwise the value SOCKET_ERROR is returned, and a specific error
|
|
number is available in lpErrno.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
} // WSPCleanup
|
|
|
|
|
|
INT
|
|
WSPAPI
|
|
WSPCloseSocket(
|
|
IN SOCKET s,
|
|
OUT LPINT lpErrno
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine closes a socket. More precisely, it releases the socket
|
|
descriptor s, so that further references to s should fail with the error
|
|
WSAENOTSOCK. If this is the last reference to an underlying socket, the
|
|
associated naming information and queued data are discarded. Any blocking,
|
|
asynchronous or overlapped calls pending on the socket (issued by any
|
|
thread in this process) are canceled without posting any notification
|
|
messages, signaling any event objects or invoking any completion routines.
|
|
In this case, the pending overlapped operations fail with the error status
|
|
WSA_OPERATION_ABORTED. FD_CLOSE will not be posted after WSPCloseSocket()
|
|
is called.
|
|
|
|
WSPClosesocket() behavior is summarized as follows:
|
|
|
|
If SO_DONTLINGER enabled (the default setting) WSPCloseSocket()
|
|
returns immediately - connection is gracefully closed "in
|
|
the background".
|
|
|
|
If SO_LINGER enabled with a zero timeout, WSPCloseSocket()
|
|
returns immediately - connection is reset/aborted.
|
|
|
|
If SO_LINGER enabled with non-zero timeout:
|
|
|
|
- With a blocking socket, WSPCloseSocket() blocks
|
|
until all data sent or timeout expires.
|
|
|
|
- With a non-blocking socket, WSPCloseSocket()
|
|
returns immediately indicating failure.
|
|
|
|
The semantics of WSPCloseSocket() are affected by the socket options
|
|
SO_LINGER and SO_DONTLINGER as follows:
|
|
|
|
Option Interval Type of close Wait for close?
|
|
~~~~~~ ~~~~~~~~ ~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~
|
|
SO_DONTLINGER Don't care Graceful No
|
|
SO_LINGER Zero Hard No
|
|
SO_LINGER Non-zero Graceful Yes
|
|
|
|
If SO_LINGER is set (i.e. the l_onoff field of the linger structure is
|
|
non-zero) and the timeout interval, l_linger, is zero, WSPClosesocket()
|
|
is not blocked even if queued data has not yet been sent or acknowledged.
|
|
This is called a "hard" or "abortive" close, because the socket's virtual
|
|
circuit is reset immediately, and any unsent data is lost. Any WSPRecv()
|
|
call on the remote side of the circuit will fail with WSAECONNRESET.
|
|
|
|
If SO_LINGER is set with a non-zero timeout interval on a blocking socket,
|
|
the WSPClosesocket() call blocks on a blocking socket until the remaining
|
|
data has been sent or until the timeout expires. This is called a graceful
|
|
disconnect. If the timeout expires before all data has been sent, the
|
|
service provider should abort the connection before WSPClosesocket()
|
|
returns.
|
|
|
|
Enabling SO_LINGER with a non-zero timeout interval on a non-blocking
|
|
socket is not recommended. In this case, the call to WSPClosesocket() will
|
|
fail with an error of WSAEWOULDBLOCK if the close operation cannot be
|
|
completed immediately. If WSPClosesocket() fails with WSAEWOULDBLOCK the
|
|
socket handle is still valid, and a disconnect is not initiated. The
|
|
WinSock SPI client must call WSPClosesocket() again to close the socket,
|
|
although WSPClosesocket() may continue to fail unless the WinSock SPI
|
|
client disables SO_DONTLINGER, enables SO_LINGER with a zero timeout, or
|
|
calls WSPShutdown() to initiate closure.
|
|
|
|
If SO_DONTLINGER is set on a stream socket (i.e. the l_onoff field of the
|
|
linger structure is zero), the WSPClosesocket() call will return
|
|
immediately. However, any data queued for transmission will be sent if
|
|
possible before the underlying socket is closed. This is called a graceful
|
|
disconnect and is the default behavior. Note that in this case the WinSock
|
|
provider is allowed to retain any resources associated with the socket
|
|
until such time as the graceful disconnect has completed or the provider
|
|
aborts the connection due to an inability to complete the operation in a
|
|
provider-determined amount of time. This may affect Winsock clients which
|
|
expect to use all available sockets.
|
|
|
|
Arguments:
|
|
|
|
s - A descriptor identifying a socket.
|
|
|
|
lpErrno - A pointer to the error code.
|
|
|
|
Return Value:
|
|
|
|
If no error occurs, WSPCloseSocket() returns 0. Otherwise, a value of
|
|
SOCKET_ERROR is returned, and a specific error code is available
|
|
in lpErrno.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
} // WSPCloseSocket
|
|
|
|
|
|
INT
|
|
WSPAPI
|
|
WSPConnect(
|
|
IN SOCKET s,
|
|
IN const struct sockaddr FAR * name,
|
|
IN int namelen,
|
|
IN LPWSABUF lpCallerData,
|
|
OUT LPWSABUF lpCalleeData,
|
|
IN LPQOS lpSQOS,
|
|
IN LPQOS lpGQOS,
|
|
OUT LPINT lpErrno
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is used to create a connection to the specified destination,
|
|
and to perform a number of other ancillary operations that occur at
|
|
connect time as well. If the socket, s, is unbound, unique values are
|
|
assigned to the local association by the system, and the socket is marked
|
|
as bound.
|
|
|
|
For connection-oriented sockets (e.g., type SOCK_STREAM), an active
|
|
connection is initiated to the specified host using name (an address in
|
|
the name space of the socket; for a detailed description, please see
|
|
WSPBind()). When this call completes successfully, the socket is ready to
|
|
send/receive data. If the address field of the name structure is all
|
|
zeroes, WSPConnect() will return the error WSAEADDRNOTAVAIL. Any attempt
|
|
to re-connect an active connection will fail with the error code
|
|
WSAEISCONN.
|
|
|
|
For a connectionless socket (e.g., type SOCK_DGRAM), the operation
|
|
performed by WSPConnect() is to establish a default destination address
|
|
so that the socket may be used with subsequent connection-oriented send
|
|
and receive operations (WSPSend(),WSPRecv()). Any datagrams received from
|
|
an address other than the destination address specified will be discarded.
|
|
If the address field of the name structure is all zeroes, the socket will
|
|
be "dis-connected" - the default remote address will be indeterminate,
|
|
so WSPSend() and WSPRecv() calls will return the error code WSAENOTCONN,
|
|
although WSPSendTo() and WSPRecvFrom() may still be used. The default
|
|
destination may be changed by simply calling WSPConnect() again, even if
|
|
the socket is already "connected". Any datagrams queued for receipt are
|
|
discarded if name is different from the previous WSPConnect().
|
|
|
|
For connectionless sockets, name may indicate any valid address, including
|
|
a broadcast address. However, to connect to a broadcast address, a socket
|
|
must have WSPSetSockOpt() SO_BROADCAST enabled, otherwise WSPConnect()
|
|
will fail with the error code WSAEACCES.
|
|
|
|
On connectionless sockets, exchange of user to user data is not possible
|
|
and the corresponding parameters will be silently ignored.
|
|
|
|
The WinSock SPI client is responsible for allocating any memory space
|
|
pointed to directly or indirectly by any of the parameters it specifies.
|
|
|
|
The lpCallerData is a value parameter which contains any user data that
|
|
is to be sent along with the connection request. If lpCallerData is NULL,
|
|
no user data will be passed to the peer. The lpCalleeData is a result
|
|
parameter which will reference any user data passed back from the peer as
|
|
part of the connection establishment. lpCalleeData->len initially
|
|
contains the length of the buffer allocated by the WinSock SPI client
|
|
and pointed to by lpCalleeData->buf. lpCalleeData->len will be set to 0
|
|
if no user data has been passed back. The lpCalleeData information will
|
|
be valid when the connection operation is complete. For blocking sockets,
|
|
this will be when the WSPConnect() function returns. For non-blocking
|
|
sockets, this will be after the FD_CONNECT notification has occurred. If
|
|
lpCalleeData is NULL, no user data will be passed back. The exact format
|
|
of the user data is specific to the address family to which the socket
|
|
belongs and/or the applications involved.
|
|
|
|
At connect time, a WinSock SPI client may use the lpSQOS and/or lpGQOS
|
|
parameters to override any previous QOS specification made for the socket
|
|
via WSPIoctl() with either the SIO_SET_QOS or SIO_SET_GROUP_QOS opcodes.
|
|
|
|
lpSQOS specifies the flow specs for socket s, one for each direction,
|
|
followed by any additional provider-specific parameters. If either the
|
|
associated transport provider in general or the specific type of socket
|
|
in particular cannot honor the QOS request, an error will be returned as
|
|
indicated below. The sending or receiving flow spec values will be ignored,
|
|
respectively, for any unidirectional sockets. If no provider-specific
|
|
parameters are supplied, the buf and len fields of lpSQOS->ProviderSpecific
|
|
should be set to NULL and 0, respectively. A NULL value for lpSQOS
|
|
indicates no application supplied QOS.
|
|
|
|
lpGQOS specifies the flow specs for the socket group (if applicable), one
|
|
for each direction, followed by any additional provider-specific
|
|
parameters. If no provider- specific parameters are supplied, the buf and
|
|
len fields of lpSQOS->ProviderSpecific should be set to NULL and 0,
|
|
respectively. A NULL value for lpGQOS indicates no application-supplied
|
|
group QOS. This parameter will be ignored if s is not the creator of the
|
|
socket group.
|
|
|
|
When connected sockets break (i.e. become closed for whatever reason),
|
|
they should be discarded and recreated. It is safest to assume that when
|
|
things go awry for any reason on a connected socket, the WinSock SPI
|
|
client must discard and recreate the needed sockets in order to return
|
|
to a stable point.
|
|
|
|
Arguments:
|
|
|
|
s - A descriptor identifying an unconnected socket.
|
|
|
|
name- The name of the peer to which the socket is to be connected.
|
|
|
|
namelen - The length of the name.
|
|
|
|
lpCallerData - A pointer to the user data that is to be transferred
|
|
to the peer during connection establishment.
|
|
|
|
lpCalleeData - A pointer to a buffer into which may be copied any user
|
|
data received from the peer during connection establishment.
|
|
|
|
lpSQOS - A pointer to the flow specs for socket s, one for each
|
|
direction.
|
|
|
|
lpGQOS - A pointer to the flow specs for the socket group (if
|
|
applicable).
|
|
|
|
lpErrno - A pointer to the error code.
|
|
|
|
Return Value:
|
|
|
|
If no error occurs, WSPConnect() returns 0. Otherwise, it returns
|
|
SOCKET_ERROR, and a specific error code is available in lpErrno.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
} // WSPConnect
|
|
|
|
|
|
INT
|
|
WSPAPI
|
|
WSPDuplicateSocket(
|
|
IN SOCKET s,
|
|
IN DWORD dwProcessId,
|
|
OUT LPWSAPROTOCOL_INFOW lpProtocolInfo,
|
|
OUT LPINT lpErrno
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
A source process calls WSPDuplicateSocket() to obtain a special
|
|
WSAPROTOCOL_INFOW structure. It uses some interprocess communications
|
|
(IPC) mechanism to pass the contents of this structure to a target
|
|
process, which in turn uses it in a call to WSPSocket() to obtain a
|
|
descriptor for the duplicated socket. Note that the special
|
|
WSAPROTOCOL_INFOW structure may only be used once by the target process.
|
|
|
|
It is the service provider's responsibility to perform whatever operations
|
|
are needed in the source process context and to create a WSAPROTOCOL_INFOW
|
|
structure that will be recognized when it subsequently appears as a
|
|
parameter to WSPSocket() in the target processes' context. The provider
|
|
must then return a socket descriptor that references a common underlying
|
|
socket. The dwProviderReserved field of the WSAPROTOCOL_INFOW struct is
|
|
available for the service provider's use, and may be used to store any
|
|
useful context information, including a duplicated handle.
|
|
|
|
When new socket descriptors are allocated IFS providers must call
|
|
WPUModifyIFSHandle() and non-IFS providers must call
|
|
WPUCreateSocketHandle().
|
|
|
|
The descriptors that reference a shared socket may be used independently
|
|
as far as I/O is concerned. However, the WinSock interface does not
|
|
implement any type of access control, so it is up to the processes
|
|
involved to coordinate their operations on a shared socket. A typical use
|
|
for shared sockets is to have one process that is responsible for
|
|
creating sockets and establishing connections, hand off sockets to
|
|
other processes which are responsible for information exchange.
|
|
|
|
Since what is duplicated are the socket descriptors and not the underlying
|
|
socket, all of the state associated with a socket is held in common across
|
|
all the descriptors. For example a WSPSetSockOpt() operation performed
|
|
using one descriptor is subsequently visible using a WSPGetSockOpt() from
|
|
any or all descriptors. A process may call WSPClosesocket() on a
|
|
duplicated socket and the descriptor will become deallocated. The
|
|
underlying socket, however, will remain open until WSPClosesocket() is
|
|
called by the last remaining descriptor.
|
|
|
|
Notification on shared sockets is subject to the usual constraints of
|
|
WSPAsyncSelect() and WSPEventSelect(). Issuing either of these calls
|
|
using any of the shared descriptors cancels any previous event
|
|
registration for the socket, regardless of which descriptor was used to
|
|
make that registration. Thus, for example, a shared socket cannot deliver
|
|
FD_READ events to process A and FD_WRITE events to process B. For
|
|
situations when such tight coordination is required, it is suggested that
|
|
developers use threads instead of separate processes.
|
|
|
|
Arguments:
|
|
|
|
s - Specifies the local socket descriptor.
|
|
|
|
dwProcessId - Specifies the ID of the target process for which the
|
|
shared socket will be used.
|
|
|
|
lpProtocolInfo - A pointer to a buffer allocated by the client that
|
|
is large enough to contain a WSAPROTOCOL_INFOW struct. The service
|
|
provider copies the protocol info struct contents to this buffer.
|
|
|
|
lpErrno - A pointer to the error code.
|
|
|
|
Return Value:
|
|
|
|
If no error occurs, WSPDuplicateSocket() returns zero. Otherwise, the
|
|
value of SOCKET_ERROR is returned, and a specific error number is
|
|
available in lpErrno.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
} // WSPDuplicateSocket
|
|
|
|
|
|
INT
|
|
WSPAPI
|
|
WSPEnumNetworkEvents(
|
|
IN SOCKET s,
|
|
IN WSAEVENT hEventObject,
|
|
OUT LPWSANETWORKEVENTS lpNetworkEvents,
|
|
OUT LPINT lpErrno
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is used to report which network events have occurred for the
|
|
indicated socket since the last invocation of this routine. It is intended
|
|
for use in conjunction with WSPEventSelect(), which associates an event
|
|
object with one or more network events. Recording of network events
|
|
commences when WSPEventSelect() is called with a non-zero lNetworkEvents
|
|
parameter and remains in effect until another call is made to
|
|
WSPEventSelect() with the lNetworkEvents parameter set to zero, or until a
|
|
call is made to WSPAsyncSelect().
|
|
|
|
The socket's internal record of network events is copied to the structure
|
|
referenced by lpNetworkEvents, whereafter the internal network events
|
|
record is cleared. If hEventObject is non-null, the indicated event object
|
|
is also reset. The WinSock provider guarantees that the operations of
|
|
copying the network event record, clearing it and resetting any associated
|
|
event object are atomic, such that the next occurrence of a nominated
|
|
network event will cause the event object to become set. In the case of
|
|
this function returning SOCKET_ERROR, the associated event object is not
|
|
reset and the record of network events is not cleared.
|
|
|
|
The WSANETWORKEVENTS structure is defined as follows:
|
|
|
|
typedef struct _WSANETWORKEVENTS {
|
|
long lNetworkEvents;
|
|
int iErrorCodes[FD_MAX_EVENTS];
|
|
} WSANETWORKEVENTS, FAR * LPWSANETWORKEVENTS;
|
|
|
|
The lNetworkEvent field of the structure indicates which of the FD_XXX
|
|
network events have occurred. The iErrorCodes array is used to contain any
|
|
associated error codes, with array index corresponding to the position of
|
|
event bits in lNetworkEvents. The identifiers FD_READ_BIT, FD_WRITE_BIT,
|
|
etc. may be used to index the iErrorCodes array.
|
|
|
|
Arguments:
|
|
|
|
s - A descriptor identifying the socket.
|
|
|
|
hEventObject - An optional handle identifying an associated event
|
|
object to be reset.
|
|
|
|
lpNetworkEvents - A pointer to a WSANETWORKEVENTS struct which is
|
|
filled with a record of occurred network events and any associated
|
|
error codes.
|
|
|
|
lpErrno - A pointer to the error code.
|
|
|
|
Return Value:
|
|
|
|
The return value is 0 if the operation was successful. Otherwise the value
|
|
SOCKET_ERROR is returned, and a specific error number is available in
|
|
lpErrno.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
} // WSPEnumNetworkEvents
|
|
|
|
|
|
INT
|
|
WSPAPI
|
|
WSPEventSelect(
|
|
IN SOCKET s,
|
|
IN WSAEVENT hEventObject,
|
|
IN long lNetworkEvents,
|
|
OUT LPINT lpErrno
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is used to specify an event object, hEventObject, to be
|
|
associated with the selected network events, lNetworkEvents. The socket
|
|
for which an event object is specified is identified by s. The event
|
|
object is set when any of the nominated network events occur.
|
|
|
|
WSPEventSelect() operates very similarly to WSPAsyncSelect(), the
|
|
difference being in the actions taken when a nominated network event
|
|
occurs. Whereas WSPAsyncSelect() causes a WinSock SPI client-specified
|
|
Windows message to be posted, WSPEventSelect() sets the associated event
|
|
object and records the occurrence of this event in an internal network
|
|
event record. A WinSock SPI client can use WSPEnumNetworkEvents() to
|
|
retrieve the contents of the internal network event record and thus
|
|
determine which of the nominated network events have occurred.
|
|
|
|
This routine automatically sets socket s to non-blocking mode, regardless
|
|
of the value of lNetworkEvents.
|
|
|
|
The lNetworkEvents parameter is constructed by OR'ing any of the values
|
|
specified in the following list.
|
|
|
|
Value Meaning
|
|
~~~~~ ~~~~~~~
|
|
FD_READ Issue notification of readiness for reading.
|
|
FD_WRITE Issue notification of readiness for writing.
|
|
FD_OOB Issue notification of the arrival of out-of-band data.
|
|
FD_ACCEPT Issue notification of incoming connections.
|
|
FD_CONNECT Issue notification of completed connection.
|
|
FD_CLOSE Issue notification of socket closure.
|
|
FD_QOS Issue notification of socket Quality of Service (QOS)
|
|
changes.
|
|
FD_GROUP_QOS Issue notification of socket group Quality of Service
|
|
(QOS) changes.
|
|
|
|
Issuing a WSPEventSelect() for a socket cancels any previous
|
|
WSPAsyncSelect() or WSPEventSelect() for the same socket and clears the
|
|
internal network event record. For example, to associate an event object
|
|
with both reading and writing network events, the WinSock SPI client must
|
|
call WSPEventSelect() with both FD_READ and FD_WRITE, as follows:
|
|
|
|
rc = WSPEventSelect(s, hEventObject, FD_READ | FD_WRITE);
|
|
|
|
It is not possible to specify different event objects for different
|
|
network events. The following code will not work; the second call will
|
|
cancel the effects of the first, and only FD_WRITE network event will be
|
|
associated with hEventObject2:
|
|
|
|
rc = WSPEventSelect(s, hEventObject1, FD_READ);
|
|
rc = WSPEventSelect(s, hEventObject2, FD_WRITE); //bad
|
|
|
|
To cancel the association and selection of network events on a socket,
|
|
lNetworkEvents should be set to zero, in which case the hEventObject
|
|
parameter will be ignored.
|
|
|
|
rc = WSPEventSelect(s, hEventObject, 0);
|
|
|
|
Closing a socket with WSPCloseSocket() also cancels the association and
|
|
selection of network events specified in WSPEventSelect() for the socket.
|
|
The WinSock SPI client, however, still must call WSACloseEvent() to
|
|
explicitly close the event object and free any resources.
|
|
|
|
Since a WSPAccept()'ed socket has the same properties as the listening
|
|
socket used to accept it, any WSPEventSelect() association and network
|
|
events selection set for the listening socket apply to the accepted socket.
|
|
For example, if a listening socket has WSPEventSelect() association of
|
|
hEventOject with FD_ACCEPT, FD_READ, and FD_WRITE, then any socket
|
|
accepted on that listening socket will also have FD_ACCEPT, FD_READ, and
|
|
FD_WRITE network events associated with the same hEventObject. If a
|
|
different hEventObject or network events are desired, the WinSock SPI
|
|
client should call WSPEventSelect(), passing the accepted socket and the
|
|
desired new information.
|
|
|
|
Having successfully recorded the occurrence of the network event and
|
|
signaled the associated event object, no further actions are taken for
|
|
that network event until the WinSock SPI client makes the function call
|
|
which implicitly reenables the setting of that network event and signaling
|
|
of the associated event object.
|
|
|
|
Event Re-enabling functions
|
|
~~~~~ ~~~~~~~~~~~~~~~~~~~~~
|
|
FD_READ WSPRecv() or WSPRecvFrom().
|
|
FD_WRITE WSPSend() or WSPSendTo().
|
|
FD_OOB WSPRecv() or WSPRecvFrom().
|
|
FD_ACCEPT WSPAccept() unless the error code returned is
|
|
WSATRY_AGAIN indicating that the condition
|
|
function returned CF_DEFER.
|
|
FD_CONNECT NONE
|
|
FD_CLOSE NONE
|
|
FD_QOS WSPIoctl() with SIO_GET_QOS
|
|
FD_GROUP_QOS WSPIoctl() with SIO_GET_GROUP_QOS
|
|
|
|
Any call to the reenabling routine, even one which fails, results in
|
|
reenabling of recording and signaling for the relevant network event and
|
|
event object, respectively.
|
|
|
|
For FD_READ, FD_OOB, and FD_ACCEPT network events, network event recording
|
|
and event object signaling are "level-triggered." This means that if the
|
|
reenabling routine is called and the relevant network condition is still
|
|
valid after the call, the network event is recorded and the associated
|
|
event object is signaled . This allows a WinSock SPI client to be event-
|
|
driven and not be concerned with the amount of data that arrives at any one
|
|
time. Consider the following sequence:
|
|
|
|
1. The service provider receives 100 bytes of data on socket s,
|
|
records the FD_READ network event and signals the associated
|
|
event object.
|
|
2. The WinSock SPI client issues WSPRecv( s, buffptr, 50, 0) to
|
|
read 50 bytes.
|
|
3. The service provider records the FD_READ network event and
|
|
signals the associated event object again since there is still
|
|
data to be read.
|
|
|
|
With these semantics, a WinSock SPI client need not read all available data
|
|
in response to an FD_READ network event --a single WSPRecv() in response to
|
|
each FD_READ network event is appropriate.
|
|
|
|
The FD_QOS and FD_GROUP_QOS events are considered edge triggered. A message
|
|
will be posted exactly once when a QOS change occurs. Further indications
|
|
will not be issued until either the service provider detects a further
|
|
change in QOS or the WinSock SPI client renegotiates the QOS for the
|
|
socket.
|
|
|
|
If a network event has already happened when the WinSock SPI client calls
|
|
WSPEventSelect() or when the reenabling function is called, then a network
|
|
event is recorded and the associated event object is signaled as
|
|
appropriate. For example, consider the following sequence:
|
|
|
|
1. A WinSock SPI client calls WSPListen().
|
|
2. A connect request is received but not yet accepted.
|
|
3. The WinSock SPI client calls WSPEventSelect() specifying that
|
|
it is interested in the FD_ACCEPT network event for the socket.
|
|
The service provider records the FD_ACCEPT network event and
|
|
signals the associated event object immediately.
|
|
|
|
The FD_WRITE network event is handled slightly differently. An FD_WRITE
|
|
network event is recorded when a socket is first connected with
|
|
WSPConnect() or accepted with WSPAccept(), and then after a WSPSend() or
|
|
WSPSendTo() fails with WSAEWOULDBLOCK and buffer space becomes available.
|
|
Therefore, a WinSock SPI client can assume that sends are possible
|
|
starting from the first FD_WRITE network event setting and lasting until
|
|
a send returns WSAEWOULDBLOCK. After such a failure the WinSock SPI client
|
|
will find out that sends are again possible when an FD_WRITE network event
|
|
is recorded and the associated event object is signaled.
|
|
|
|
The FD_OOB network event is used only when a socket is configured to
|
|
receive out-of-band data separately. If the socket is configured to receive
|
|
out-of-band data in-line, the out-of-band (expedited) data is treated as
|
|
normal data and the WinSock SPI client should register an interest in, and
|
|
will get, FD_READ network event, not FD_OOB network event. A WinSock SPI
|
|
client may set or inspect the way in which out-of-band data is to be
|
|
handled by using WSPSetSockOpt() or WSPGetSockOpt() for the SO_OOBINLINE
|
|
option.
|
|
|
|
The error code in an FD_CLOSE network event indicates whether the socket
|
|
close was graceful or abortive. If the error code is 0, then the close was
|
|
graceful; if the error code is WSAECONNRESET, then the socket's virtual
|
|
circuit was reset. This only applies to connection-oriented sockets such
|
|
as SOCK_STREAM.
|
|
|
|
The FD_CLOSE network event is recorded when a close indication is received
|
|
for the virtual circuit corresponding to the socket. In TCP terms, this
|
|
means that the FD_CLOSE is recorded when the connection goes into the
|
|
FIN WAIT or CLOSE WAIT states. This results from the remote end performing
|
|
a WSPShutdown() on the send side or a WSPCloseSocket().
|
|
|
|
Service providers shall record ONLY an FD_CLOSE network event to indicate
|
|
closure of a virtual circuit, they shall NOT record an FD_READ network
|
|
event to indicate this condition.
|
|
|
|
The FD_QOS or FD_GROUP_QOS network event is recorded when any field in the
|
|
flow spec associated with socket s or the socket group that s belongs to
|
|
has changed, respectively. This change must be made available to WinSock
|
|
SPI clients via the WSPIoctl() function with SIO_GET_QOS and/or
|
|
SIO_GET_GROUP_QOS to retrieve the current QOS for socket s or for the
|
|
socket group s belongs to, respectively.
|
|
|
|
Arguments:
|
|
|
|
s - A descriptor identifying the socket.
|
|
|
|
hEventObject - A handle identifying the event object to be associated
|
|
with the supplied set of network events.
|
|
|
|
lNetworkEvents - A bitmask which specifies the combination of network
|
|
events in which the WinSock SPI client has interest.
|
|
|
|
lpErrno - A pointer to the error code.
|
|
|
|
Return Value:
|
|
|
|
The return value is 0 if the WinSock SPI client's specification of the
|
|
network events and the associated event object was successful.
|
|
Otherwise the value SOCKET_ERROR is returned, and a specific error
|
|
number is available in lpErrno.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
} // WSPEventSelect
|
|
|
|
|
|
BOOL
|
|
WSPAPI
|
|
WSPGetOverlappedResult(
|
|
IN SOCKET s,
|
|
IN LPWSAOVERLAPPED lpOverlapped,
|
|
OUT LPDWORD lpcbTransfer,
|
|
IN BOOL fWait,
|
|
OUT LPDWORD lpdwFlags,
|
|
OUT LPINT lpErrno
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
The results reported by the WSPGetOverlappedResult() function are those
|
|
of the specified socket's last overlapped operation to which the specified
|
|
WSAOVERLAPPED structure was provided, and for which the operation's results
|
|
were pending. A pending operation is indicated when the function that
|
|
started the operation returns FALSE, and the lpErrno is WSA_IO_PENDING.
|
|
When an I/O operation is pending, the function that started the operation
|
|
resets the hEvent member of the WSAOVERLAPPED structure to the nonsignaled
|
|
state. Then when the pending operation has been completed, the system sets
|
|
the event object to the signaled state.
|
|
|
|
If the fWait parameter is TRUE, WSPGetOverlappedResult() determines whether
|
|
the pending operation has been completed by blocking and waiting for the
|
|
event object to be in the signaled state.
|
|
|
|
Arguments:
|
|
|
|
s - Identifies the socket. This is the same socket that was specified
|
|
when the overlapped operation was started by a call to WSPRecv(),
|
|
WSPRecvFrom(), WSPSend(), WSPSendTo(), or WSPIoctl().
|
|
|
|
lpOverlapped - Points to a WSAOVERLAPPED structure that was specified
|
|
when the overlapped operation was started.
|
|
|
|
lpcbTransfer - Points to a 32-bit variable that receives the number of
|
|
bytes that were actually transferred by a send or receive operation,
|
|
or by WSPIoctl().
|
|
|
|
fWait - Specifies whether the function should wait for the pending
|
|
overlapped operation to complete. If TRUE, the function does not
|
|
return until the operation has been completed. If FALSE and the
|
|
operation is still pending, the function returns FALSE and lpErrno
|
|
is WSA_IO_INCOMPLETE.
|
|
|
|
lpdwFlags - Points to a 32-bit variable that will receive one or more
|
|
flags that supplement the completion status. If the overlapped
|
|
operation was initiated via WSPRecv() or WSPRecvFrom(), this
|
|
parameter will contain the results value for lpFlags parameter.
|
|
|
|
lpErrno - A pointer to the error code.
|
|
|
|
Return Value:
|
|
|
|
If WSPGetOverlappedResult() succeeds, the return value is TRUE. This
|
|
means that the overlapped operation has completed successfully
|
|
and that the value pointed to by lpcbTransfer has been updated.
|
|
If WSPGetOverlappedResult() returns FALSE, this means that either
|
|
the overlapped operation has not completed or the overlapped
|
|
operation completed but with errors, or that completion status
|
|
could not be determined due to errors in one or more parameters
|
|
to WSPGetOverlappedResult(). On failure, the value pointed to by
|
|
lpcbTransfer will not be updated. lpErrno indicates the cause of
|
|
the failure (either of WSPGetOverlappedResult() or of the
|
|
associated overlapped operation).
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
} // WSPGetOverlappedResult
|
|
|
|
|
|
INT
|
|
WSPAPI
|
|
WSPGetPeerName(
|
|
IN SOCKET s,
|
|
OUT struct sockaddr FAR * name,
|
|
IN OUT LPINT namelen,
|
|
OUT LPINT lpErrno
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine supplies the name of the peer connected to the socket s and
|
|
stores it in the struct sockaddr referenced by name. It may be used only
|
|
on a connected socket. For datagram sockets, only the name of a peer
|
|
specified in a previous WSPConnect() call will be returned - any name
|
|
specified by a previous WSPSendTo() call will not be returned by
|
|
WSPGetPeerName().
|
|
|
|
On return, the namelen argument contains the actual size of the name
|
|
returned in bytes.
|
|
|
|
Arguments:
|
|
|
|
s - A descriptor identifying a connected socket.
|
|
|
|
name - A pointer to the structure which is to receive the name of the
|
|
peer.
|
|
|
|
namelen - A pointer to an integer which, on input, indicates the size
|
|
of the structure pointed to by name, and on output indicates the
|
|
size of the returned name.
|
|
|
|
lpErrno - A pointer to the error code.
|
|
|
|
Return Value:
|
|
|
|
If no error occurs, WSPGetPeerName() returns 0. Otherwise, a value of
|
|
SOCKET_ERROR is returned, and a specific error code is available
|
|
in lpErrno.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
} // WSPGetPeerName
|
|
|
|
|
|
BOOL
|
|
WSPAPI
|
|
WSPGetQOSByName(
|
|
IN SOCKET s,
|
|
IN LPWSABUF lpQOSName,
|
|
OUT LPQOS lpQOS,
|
|
OUT LPINT lpErrno
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Clients may use this routine to initialize a QOS structure to a set of
|
|
known values appropriate for a particular service class or media type.
|
|
These values are stored in a template which is referenced by a well-known
|
|
name
|
|
|
|
Arguments:
|
|
|
|
s - A descriptor identifying a socket.
|
|
|
|
lpQOSName - Specifies the QOS template name.
|
|
|
|
lpQOS - A pointer to the QOS structure to be filled.
|
|
|
|
lpErrno - A pointer to the error code.
|
|
|
|
Return Value:
|
|
|
|
If no error occurs, WSPGetQOSByName() returns TRUE. Otherwise, a value of
|
|
FALSE is returned, and a specific error code is available in
|
|
lpErrno.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
} // WSPGetQOSByName
|
|
|
|
|
|
INT
|
|
WSPAPI
|
|
WSPGetSockName(
|
|
IN SOCKET s,
|
|
OUT struct sockaddr FAR * name,
|
|
IN OUT LPINT namelen,
|
|
OUT LPINT lpErrno
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine retrieves the current name for the specified socket descriptor
|
|
in name. It is used on a bound and/or connected socket specified by the s
|
|
parameter. The local association is returned. This call is especially
|
|
useful when a WSPConnect() call has been made without doing a WSPBind()
|
|
first; as this call provides the only means by which the local association
|
|
that has been set by the service provider can be determined.
|
|
|
|
If a socket was bound to an unspecified address (e.g., ADDR_ANY),
|
|
indicating that any of the host's addresses within the specified address
|
|
family should be used for the socket, WSPGetSockName() will not necessarily
|
|
return information about the host address, unless the socket has been
|
|
connected with WSPConnect() or WSPAccept. The WinSock SPI client must not
|
|
assume that an address will be specified unless the socket is connected.
|
|
This is because for a multi-homed host the address that will be used for
|
|
the socket is unknown until the socket is connected.
|
|
|
|
Arguments:
|
|
|
|
s - A descriptor identifying a bound socket.
|
|
|
|
name - A pointer to a structure used to supply the address (name) of
|
|
the socket.
|
|
|
|
namelen - A pointer to an integer which, on input, indicates the size
|
|
of the structure pointed to by name, and on output indicates the
|
|
size of the returned name.
|
|
|
|
lpErrno - A pointer to the error code.
|
|
|
|
Return Value:
|
|
|
|
If no error occurs, WSPGetSockName() returns 0. Otherwise, a value of
|
|
SOCKET_ERROR is returned, and a specific error code is available in
|
|
lpErrno.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
} // WSPGetSockName
|
|
|
|
|
|
INT
|
|
WSPAPI
|
|
WSPGetSockOpt(
|
|
IN SOCKET s,
|
|
IN int level,
|
|
IN int optname,
|
|
OUT char FAR * optval,
|
|
IN OUT LPINT optlen,
|
|
OUT LPINT lpErrno
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine retrieves the current value for a socket option associated
|
|
with a socket of any type, in any state, and stores the result in optval.
|
|
Options may exist at multiple protocol levels, but they are always present
|
|
at the uppermost "socket" level. Options affect socket operations, such as
|
|
the routing of packets, out-of-band data transfer, etc.
|
|
|
|
The value associated with the selected option is returned in the buffer
|
|
optval. The integer pointed to by optlen should originally contain the size
|
|
of this buffer; on return, it will be set to the size of the value
|
|
returned. For SO_LINGER, this will be the size of a struct linger; for most
|
|
other options it will be the size of an integer.
|
|
|
|
The WinSock SPI client is responsible for allocating any memory space
|
|
pointed to directly or indirectly by any of the parameters it specifies.
|
|
|
|
If the option was never set with WSPSetSockOpt(), then WSPGetSockOpt()
|
|
returns the default value for the option.
|
|
|
|
Value Type Meaning
|
|
~~~~~ ~~~~ ~~~~~~~
|
|
SO_ACCEPTCONN BOOL Socket is WSPListen()ing.
|
|
SO_BROADCAST BOOL Socket is configured for the
|
|
transmission of broadcast messages
|
|
on the socket.
|
|
SO_DEBUG BOOL Debugging is enabled.
|
|
SO_DONTROUTE BOOL Routing is disabled.
|
|
SO_GROUP_ID GROUP The identifier of the group to
|
|
which the socket belongs.
|
|
SO_GROUP_PRIORITY int The relative priority for sockets
|
|
that are part of a socket group.
|
|
SO_KEEPALIVE BOOL Keepalives are being sent.
|
|
SO_LINGER struct linger Returns the current linger options.
|
|
SO_MAX_MSG_SIZE unsigned int Maximum size of a message for
|
|
message-oriented socket types
|
|
(e.g. SOCK_DGRAM). Has no meaning
|
|
for stream-oriented sockets.
|
|
SO_OOBINLINE BOOL Out-of-band data is being received
|
|
in the normal data stream.
|
|
SO_PROTOCOL_INFOW WSAPROTOCOL_INFOW Description of the protocol info
|
|
for the protocol that is bound
|
|
to this socket.
|
|
SO_RCVBUF int Buffer size for receives.
|
|
SO_REUSEADDR BOOL The socket may be bound to an
|
|
address which is already in use.
|
|
SO_SNDBUF int Buffer size for sends.
|
|
SO_TYPE int The type of the socket (e.g.
|
|
SOCK_STREAM).
|
|
PVD_CONFIG Service An "opaque" data structure object
|
|
Provider from the service provider
|
|
Dependent associated with socket s. This
|
|
object stores the current
|
|
configuration information of the
|
|
service provider. The exact format
|
|
of this data structure is service
|
|
provider specific.
|
|
|
|
Calling WSPGetSockOpt() with an unsupported option will result in an error
|
|
code of WSAENOPROTOOPT being returned in lpErrno.
|
|
|
|
SO_DEBUG - WinSock service providers are encouraged (but not required) to
|
|
supply output debug information if the SO_DEBUG option is set by a WinSock
|
|
SPI client. The mechanism for generating the debug information and the form
|
|
it takes are beyond the scope of this specification.
|
|
|
|
SO_ERROR - The SO_ERROR option returns and resets the per-socket based
|
|
error code (which is not necessarily the same as the per-thread error code
|
|
that is maintained by the WinSock 2 DLL). A successful WinSock call on the
|
|
socket does not reset the socket-based error code returned by the SO_ERROR
|
|
option.
|
|
|
|
SO_GROUP_ID - This is a get-only socket option which supplies the
|
|
identifier of the group this socket belongs to. Note that socket group IDs
|
|
are unique across all processes for a give service provider. If this socket
|
|
is not a group socket, the value is NULL.
|
|
|
|
SO_GROUP_PRIORITY - Group priority indicates the priority of the specified
|
|
socket relative to other sockets within the socket group. Values are non-
|
|
negative integers, with zero corresponding to the highest priority.
|
|
Priority values represent a hint to the service provider about how
|
|
potentially scarce resources should be allocated. For example, whenever
|
|
two or more sockets are both ready to transmit data, the highest priority
|
|
socket (lowest value for SO_GROUP_PRIORITY) should be serviced first, with
|
|
the remainder serviced in turn according to their relative priorities.
|
|
|
|
The WSAENOPROTOOPT error is indicated for non group sockets or for service
|
|
providers which do not support group sockets.
|
|
|
|
SO_KEEPALIVE - An WinSock SPI client may request that a TCP/IP provider
|
|
enable the use of "keep-alive" packets on TCP connections by turning on the
|
|
SO_KEEPALIVE socket option. A WinSock provider need not support the use of
|
|
keep-alives: if it does, the precise semantics are implementation-specific
|
|
but should conform to section 4.2.3.6 of RFC 1122: Requirements for
|
|
Internet Hosts -- Communication Layers. If a connection is dropped as the
|
|
result of "keep-alives" the error code WSAENETRESET is returned to any
|
|
calls in progress on the socket, and any subsequent calls will fail with
|
|
WSAENOTCONN.
|
|
|
|
SO_LINGER - SO_LINGER controls the action taken when unsent data is queued
|
|
on a socket and a WSPCloseSocket() is performed. See WSPCloseSocket() for a
|
|
description of the way in which the SO_LINGER settings affect the semantics
|
|
of WSPCloseSocket(). The WinSock SPI client sets the desired behavior by
|
|
creating a struct linger (pointed to by the optval argument) with the
|
|
following elements:
|
|
|
|
struct linger {
|
|
u_short l_onoff;
|
|
u_short l_linger;
|
|
};
|
|
|
|
To enable SO_LINGER, a WinSock SPI client should set l_onoff to a non-zero
|
|
value, set l_linger to 0 or the desired timeout (in seconds), and call
|
|
WSPSetSockOpt(). To enable SO_DONTLINGER (i.e. disable SO_LINGER) l_onoff
|
|
should be set to zero and WSPSetSockOpt() should be called. Note that
|
|
enabling SO_LINGER with a non-zero timeout on a non-blocking socket is not
|
|
recommended (see WSPCloseSocket() for details).
|
|
|
|
Enabling SO_LINGER also disables SO_DONTLINGER, and vice versa. Note that
|
|
if SO_DONTLINGER is DISABLED (i.e. SO_LINGER is ENABLED) then no timeout
|
|
value is specified. In this case the timeout used is implementation
|
|
dependent. If a previous timeout has been established for a socket (by
|
|
enabling SO_LINGER), then this timeout value should be reinstated by the
|
|
service provider.
|
|
|
|
SO_MAX_MSG_SIZE - This is a get-only socket option which indicates the
|
|
maximum size of a message for message-oriented socket types (e.g.
|
|
SOCK_DGRAM) as implemented by the service provider. It has no meaning for
|
|
byte stream oriented sockets.
|
|
|
|
SO_PROTOCOL_INFO - This is a get-only option which supplies the
|
|
WSAPROTOCOL_INFOW structure associated with this socket.
|
|
|
|
SO_RCVBUF & SO_SNDBUF - When a Windows Sockets implementation supports the
|
|
SO_RCVBUF and SO_SNDBUF options, a WinSock SPI client may request different
|
|
buffer sizes (larger or smaller). The call may succeed even though the
|
|
service provider did not make available the entire amount requested. A
|
|
WinSock SPI client must call WSPGetSockOpt() with the same option to check
|
|
the buffer size actually provided.
|
|
|
|
SO_REUSEADDR - By default, a socket may not be bound (see WSPBind()) to a
|
|
local address which is already in use. On occasions, however, it may be
|
|
desirable to "re-use" an address in this way. Since every connection is
|
|
uniquely identified by the combination of local and remote addresses, there
|
|
is no problem with having two sockets bound to the same local address as
|
|
long as the remote addresses are different. To inform the WinSock provider
|
|
that a WSPBind() on a socket should be allowed to bind to a local address
|
|
that is already in use by another socket, the WinSock SPI client should set
|
|
the SO_REUSEADDR socket option for the socket before issuing the WSPBind().
|
|
Note that the option is interpreted only at the time of the WSPBind(): it
|
|
is therefore unnecessary (but harmless) to set the option on a socket which
|
|
is not to be bound to an existing address, and setting or resetting the
|
|
option after the WSPBind() has no effect on this or any other socket.
|
|
|
|
PVD_CONFIG - This object stores the configuration information for the
|
|
service provider associated with socket s. The exact format of this data
|
|
structure is service provider specific.
|
|
|
|
Arguments:
|
|
|
|
s - A descriptor identifying a socket.
|
|
|
|
level - The level at which the option is defined; the supported levels
|
|
include SOL_SOCKET.
|
|
|
|
optname - The socket option for which the value is to be retrieved.
|
|
|
|
optval - A pointer to the buffer in which the value for the requested
|
|
option is to be returned.
|
|
|
|
optlen - A pointer to the size of the optval buffer.
|
|
|
|
lpErrno - A pointer to the error code.
|
|
|
|
Return Value:
|
|
|
|
If no error occurs, WSPGetSockOpt() returns 0. Otherwise, a value of
|
|
SOCKET_ERROR is returned, and a specific error code is available in
|
|
lpErrno.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
} // WSPGetSockOpt
|
|
|
|
|
|
INT
|
|
WSPAPI
|
|
WSPIoctl(
|
|
IN SOCKET s,
|
|
IN DWORD dwIoControlCode,
|
|
IN LPVOID lpvInBuffer,
|
|
IN DWORD cbInBuffer,
|
|
OUT LPVOID lpvOutBuffer,
|
|
IN DWORD cbOutBuffer,
|
|
OUT LPDWORD lpcbBytesReturned,
|
|
IN LPWSAOVERLAPPED lpOverlapped,
|
|
IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
|
|
IN LPWSATHREADID lpThreadId,
|
|
OUT LPINT lpErrno
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is used to set or retrieve operating parameters associated
|
|
with the socket, the transport protocol, or the communications subsystem.
|
|
For non-overlapped sockets, lpOverlapped and lpCompletionRoutine
|
|
parameters are ignored, and this routine may block if socket s is in the
|
|
blocking mode. Note that if socket s is in the non-blocking mode, this
|
|
routine may return WSAEWOULDBLOCK if the specified operation cannot be
|
|
finished immediately. In this case, the WinSock SPI client should change
|
|
the socket to the blocking mode and reissue the request. For overlapped
|
|
sockets, operations that cannot be completed immediately will be initiated,
|
|
and completion will be indicated at a later time. The final completion
|
|
status is retrieved via the WSPGetOverlappedResult().
|
|
|
|
In as much as the dwIoControlCode parameter is now a 32 bit entity, it is
|
|
possible to adopt an encoding scheme that provides a convenient way to
|
|
partition the opcode identifier space. The dwIoControlCode parameter is
|
|
architected to allow for protocol and vendor independence when adding new
|
|
control codes, while retaining backward compatibility with Windows Sockets
|
|
1.1 and Unix control codes. The dwIoControlCode parameter has the following
|
|
form:
|
|
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
|3|3|2|2|2|2|2|2|2|2|2|2|1|1|1|1|1|1|1|1|1|1| | | | | | | | | | |
|
|
|1|0|9|8|7|6|5|4|3|2|1|0|9|8|7|6|5|4|3|2|1|0|9|8|7|6|5|4|3|2|1|0|
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
|I|O|V| T |Vendor/Address Family| Code |
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
|
|
I - Set if the input buffer is valid for the code, as with IOC_IN.
|
|
|
|
O - Set if the output buffer is valid for the code, as with IOC_OUT.
|
|
Note that for codes with both input and output parameters, both I
|
|
and O will be set.
|
|
|
|
V - Set if there are no parameters for the code, as with IOC_VOID.
|
|
|
|
T - A two-bit quantity which defines the type of ioctl. The following
|
|
values are defined:
|
|
|
|
0 - The ioctl is a standard Unix ioctl code, as with FIONREAD,
|
|
FIONBIO, etc.
|
|
|
|
1 - The ioctl is a generic Windows Sockets 2 ioctl code. New
|
|
ioctl codes defined for Windows Sockets 2 will have T == 1.
|
|
|
|
2 - The ioctl applies only to a specific address family.
|
|
|
|
3 - The ioctl applies only to a specific vendor's provider. This
|
|
type allows companies to be assigned a vendor number which
|
|
appears in the Vendor/Address Family field, and then the vendor
|
|
can define new ioctls specific to that vendor without having to
|
|
register the ioctl with a clearinghouse, thereby providing vendor
|
|
flexibility and privacy.
|
|
|
|
Vendor/Address Family - An 11-bit quantity which defines the vendor
|
|
who owns the code (if T == 3) or which contains the address family
|
|
to which the code applies (if T == 2). If this is a Unix ioctl code
|
|
(T == 0) then this field has the same value as the code on Unix. If
|
|
this is a generic Windows Sockets 2 ioctl (T == 1) then this field
|
|
can be used as an extension of the "code" field to provide additional
|
|
code values.
|
|
|
|
Code - The specific ioctl code for the operation.
|
|
|
|
The following Unix commands are supported:
|
|
|
|
FIONBIO - Enable or disable non-blocking mode on socket s. lpvInBuffer
|
|
points at an unsigned long, which is non-zero if non-blocking mode is to be
|
|
enabled and zero if it is to be disabled. When a socket is created, it
|
|
operates in blocking mode (i.e. non-blocking mode is disabled). This is
|
|
consistent with BSD sockets.
|
|
|
|
The WSPAsyncSelect() or WSPEventSelect() routine automatically sets a
|
|
socket to nonblocking mode. If WSPAsyncSelect() or WSPEventSelect() has
|
|
been issued on a socket, then any attempt to use WSPIoctl() to set the
|
|
socket back to blocking mode will fail with WSAEINVAL. To set the socket
|
|
back to blocking mode, a WinSock SPI client must first disable
|
|
WSPAsyncSelect() by calling WSPAsyncSelect() with the lEvent parameter
|
|
equal to 0, or disable WSPEventSelect() by calling WSPEventSelect() with
|
|
the lNetworkEvents parameter equal to 0.
|
|
|
|
FIONREAD - Determine the amount of data which can be read atomically from
|
|
socket s. lpvOutBuffer points at an unsigned long in which WSPIoctl()
|
|
stores the result. If s is stream-oriented (e.g., type SOCK_STREAM),
|
|
FIONREAD returns the total amount of data which may be read in a single
|
|
receive operation; this is normally the same as the total amount of data
|
|
queued on the socket. If s is message-oriented (e.g., type SOCK_DGRAM),
|
|
FIONREAD returns the size of the first datagram (message) queued on the
|
|
socket.
|
|
|
|
SIOCATMARK - Determine whether or not all out-of-band data has been read.
|
|
This applies only to a socket of stream style (e.g., type SOCK_STREAM)
|
|
which has been configured for in-line reception of any out-of-band data
|
|
(SO_OOBINLINE). If no out-of-band data is waiting to be read, the operation
|
|
returns TRUE. Otherwise it returns FALSE, and the next receive operation
|
|
performed on the socket will retrieve some or all of the data preceding the "
|
|
mark"; the WinSock SPI client should use the SIOCATMARK operation to
|
|
determine whether any remains. If there is any normal data preceding the
|
|
"urgent" (out of band) data, it will be received in order. (Note that
|
|
receive operations will never mix out-of-band and normal data in the same
|
|
call.) lpvOutBuffer points at a BOOL in which WSPIoctl() stores the result.
|
|
|
|
The following WinSock 2 commands are supported:
|
|
|
|
SIO_ASSOCIATE_HANDLE (opcode setting: I, T==1) - Associate this socket with
|
|
the specified handle of a companion interface. The input buffer contains
|
|
the integer value corresponding to the manifest constant for the companion
|
|
interface (e.g., TH_NETDEV, TH_TAPI, etc.), followed by a value which is a
|
|
handle of the specified companion interface, along with any other required
|
|
information. Refer to the appropriate section in the Windows Sockets 2
|
|
Protocol-Specific Annex and/or documentation for the particular companion
|
|
interface for additional details. The total size is reflected in the input
|
|
buffer length. No output buffer is required. The WSAENOPROTOOPT error code
|
|
is indicated for service providers which do not support this ioctl.
|
|
|
|
SIO_ENABLE_CIRCULAR_QUEUEING (opcode setting: V, T==1) - Indicates to a
|
|
message-oriented service provider that a newly arrived message should
|
|
never be dropped because of a buffer queue overflow. Instead, the oldest
|
|
message in the queue should be eliminated in order to accommodate the newly
|
|
arrived message. No input and output buffers are required. Note that this
|
|
ioctl is only valid for sockets associated with unreliable, message-
|
|
oriented protocols. The WSAENOPROTOOPT error code is indicated for service
|
|
providers which do not support this ioctl.
|
|
|
|
SIO_FIND_ROUTE (opcode setting: O, T==1) - When issued, this ioctl requests
|
|
that the route to the remote address specified as a sockaddr in the input
|
|
buffer be discovered. If the address already exists in the local cache, its
|
|
entry is invalidated. In the case of Novell's IPX, this call initiates an
|
|
IPX GetLocalTarget (GLT), which queries the network for the given remote
|
|
address.
|
|
|
|
SIO_FLUSH (opcode setting: V, T==1) - Discards current contents of the
|
|
sending queue associated with this socket. No input and output buffers are
|
|
required. The WSAENOPROTOOPT error code is indicated for service providers
|
|
which do not support this ioctl.
|
|
|
|
SIO_GET_BROADCAST_ADDRESS (opcode setting: O, T==1) - This ioctl fills the
|
|
output buffer with a sockaddr struct containing a suitable broadcast
|
|
address for use with WSPIoctl().
|
|
|
|
SIO_GET_EXTENSION_FUNCTION_POINTER (opcode setting: O, I, T==1) - Retrieve
|
|
a pointer to the specified extension function supported by the associated
|
|
service provider. The input buffer contains a GUID whose value identifies
|
|
the extension function in question. The pointer to the desired function is
|
|
returned in the output buffer. Extension function identifiers are
|
|
established by service provider vendors and should be included in vendor
|
|
documentation that describes extension function capabilities and semantics.
|
|
|
|
SIO_GET_QOS (opcode setting: O,I, T==1) - Retrieve the QOS structure
|
|
associated with the socket. The input buffer is optional. Some protocols
|
|
(e.g. RSVP) allow the input buffer to be used to qualify a QOS request.
|
|
The QOS structure will be copied into the output buffer. The output buffer
|
|
must be sized large enough to be able to contain the full QOS struct. The
|
|
WSAENOPROTOOPT error code is indicated for service providers which do not
|
|
support QOS.
|
|
|
|
SIO_GET_GROUP_QOS (opcode setting: O,I, T==1) - Retrieve the QOS structure
|
|
associated with the socket group to which this socket belongs. The input
|
|
buffer is optional. Some protocols (e.g. RSVP) allow the input buffer to
|
|
be used to qualify a QOS request. The QOS structure will be copied into
|
|
the output buffer. If this socket does not belong to an appropriate socket
|
|
group, the SendingFlowspec and ReceivingFlowspec fields of the returned QOS
|
|
struct are set to NULL. The WSAENOPROTOOPT error code is indicated for
|
|
service providers which do not support QOS.
|
|
|
|
SIO_MULTIPOINT_LOOPBACK (opcode setting: I, T==1) - Controls whether data
|
|
sent in a multipoint session will also be received by the same socket on
|
|
the local host. A value of TRUE causes loopback reception to occur while a
|
|
value of FALSE prohibits this.
|
|
|
|
SIO_MULTICAST_SCOPE (opcode setting: I, T==1) - Specifies the scope over
|
|
which multicast transmissions will occur. Scope is defined as the number of
|
|
routed network segments to be covered. A scope of zero would indicate that
|
|
the multicast transmission would not be placed "on the wire" but could be
|
|
disseminated across sockets within the local host. A scope value of one
|
|
(the default) indicates that the transmission will be placed on the wire,
|
|
but will not cross any routers. Higher scope values determine the number of
|
|
routers that may be crossed. Note that this corresponds to the time-to-live
|
|
(TTL) parameter in IP multicasting.
|
|
|
|
SIO_SET_QOS (opcode setting: I, T==1) - Associate the supplied QOS
|
|
structure with the socket. No output buffer is required, the QOS structure
|
|
will be obtained from the input buffer. The WSAENOPROTOOPT error code is
|
|
indicated for service providers which do not support QOS.
|
|
|
|
SIO_SET_GROUP_QOS (opcode setting: I, T==1) - Establish the supplied QOS
|
|
structure with the socket group to which this socket belongs. No output
|
|
buffer is required, the QOS structure will be obtained from the input
|
|
buffer. The WSAENOPROTOOPT error code is indicated for service providers
|
|
which do not support QOS, or if the socket descriptor specified is not the
|
|
creator of the associated socket group.
|
|
|
|
SIO_TRANSLATE_HANDLE (opcode setting: I, O, T==1) - To obtain a
|
|
corresponding handle for socket s that is valid in the context of a
|
|
companion interface (e.g., TH_NETDEV, TH_TAPI, etc.). A manifest constant
|
|
identifying the companion interface along with any other needed parameters
|
|
are specified in the input buffer. The corresponding handle will be
|
|
available in the output buffer upon completion of this routine. Refer to
|
|
the appropriate section in the Windows Sockets 2 Protocol-Specific Annex
|
|
and/or documentation for the particular companion interface for additional
|
|
details. The WSAENOPROTOOPT error code is indicated for service providers
|
|
which do not support this ioctl for the specified companion interface.
|
|
|
|
If an overlapped operation completes immediately, WSPIoctl() returns a
|
|
value of zero and the lpNumberOfBytesReturned parameter is updated with
|
|
the number of bytes returned. If the overlapped operation is successfully
|
|
initiated and will complete later, WSPIoctl() returns SOCKET_ERROR and
|
|
indicates error code WSA_IO_PENDING. In this case, lpNumberOfBytesReturned
|
|
is not updated. When the overlapped operation completes the amount of data
|
|
transferred is indicated either via the cbTransferred parameter in the
|
|
completion routine (if specified), or via the lpcbTransfer parameter in
|
|
WSPGetOverlappedResult().
|
|
|
|
Providers must allow this routine to be called from within the completion
|
|
routine of a previous WSPRecv(), WSPRecvFrom(), WSPSend() or WSPSendTo()
|
|
function. However, for a given socket, I/O completion routines may not be
|
|
nested. This permits time-sensitive data transmissions to occur entirely
|
|
within a preemptive context.
|
|
|
|
The lpOverlapped parameter must be valid for the duration of the
|
|
overlapped operation. If multiple I/O operations are simultaneously
|
|
outstanding, each must reference a separate overlapped structure. The
|
|
WSAOVERLAPPED structure has the following form:
|
|
|
|
typedef struct _WSAOVERLAPPED {
|
|
DWORD Internal; // reserved
|
|
DWORD InternalHigh; // reserved
|
|
DWORD Offset; // reserved
|
|
DWORD OffsetHigh; // reserved
|
|
WSAEVENT hEvent;
|
|
} WSAOVERLAPPED, FAR * LPWSAOVERLAPPED;
|
|
|
|
If the lpCompletionRoutine parameter is NULL, the service provider signals
|
|
the hEvent field of lpOverlapped when the overlapped operation completes
|
|
if it contains a valid event object handle. The WinSock SPI client can use
|
|
WSPGetOverlappedResult() to wait or poll on the event object.
|
|
|
|
If lpCompletionRoutine is not NULL, the hEvent field is ignored and can be
|
|
used by the WinSock SPI client to pass context information to the
|
|
completion routine. It is the service provider's responsibility to arrange
|
|
for invocation of the client-specified completion routine when the
|
|
overlapped operation completes. Since the completion routine must be
|
|
executed in the context of the same thread that initiated the overlapped
|
|
operation, it cannot be invoked directly from the service provider. The
|
|
WinSock DLL offers an asynchronous procedure call (APC) mechanism to
|
|
facilitate invocation of completion routines.
|
|
|
|
A service provider arranges for a function to be executed in the proper
|
|
thread by calling WPUQueueApc(). Note that this routine must be invoked
|
|
while in the context of the same process (but not necessarily the same
|
|
thread) that was used to initiate the overlapped operation. It is the
|
|
service provider's responsibility to arrange for this process context to
|
|
be active prior to calling WPUQueueApc().
|
|
|
|
WPUQueueApc() takes as input parameters a pointer to a WSATHREADID
|
|
structure (supplied to the provider via the lpThreadId input parameter),
|
|
a pointer to an APC function to be invoked, and a 32 bit context value
|
|
that is subsequently passed to the APC function. Because only a single
|
|
32-bit context value is available, the APC function cannot itself be the
|
|
client-specified completion routine. The service provider must instead
|
|
supply a pointer to its own APC function which uses the supplied context
|
|
value to access the needed result information for the overlapped operation,
|
|
and then invokes the client-specified completion routine.
|
|
|
|
The prototype for the client-supplied completion routine is as follows:
|
|
|
|
void
|
|
CALLBACK
|
|
CompletionRoutine(
|
|
IN DWORD dwError,
|
|
IN DWORD cbTransferred,
|
|
IN LPWSAOVERLAPPED lpOverlapped,
|
|
IN DWORD dwFlags
|
|
);
|
|
|
|
CompletionRoutine is a placeholder for a client supplied function
|
|
name.
|
|
|
|
dwError specifies the completion status for the overlapped
|
|
operation as indicated by lpOverlapped.
|
|
|
|
cbTransferred specifies the number of bytes sent.
|
|
|
|
No flag values are currently defined and the dwFlags value will
|
|
be zero.
|
|
|
|
This routine does not return a value.
|
|
|
|
The completion routines may be called in any order, not necessarily in
|
|
the same order the overlapped operations are completed. However, the
|
|
service provider guarantees to the client that posted buffers are sent
|
|
in the same order they are supplied.
|
|
|
|
The ioctl codes with T == 0 are a subset of the ioctl codes used in
|
|
Berkeley sockets. In particular, there is no command which is equivalent
|
|
to FIOASYNC.
|
|
|
|
Arguments:
|
|
|
|
s - Handle to a socket
|
|
|
|
dwIoControlCode - Control code of operation to perform
|
|
|
|
lpvInBuffer - Address of input buffer
|
|
|
|
cbInBuffer - Size of input buffer
|
|
|
|
lpvOutBuffer - Address of output buffer
|
|
|
|
cbOutBuffer - Size of output buffer
|
|
|
|
lpcbBytesReturned - A pointer to the size of output buffer's contents.
|
|
|
|
lpOverlapped - Address of WSAOVERLAPPED structure
|
|
|
|
lpCompletionRoutine - A pointer to the completion routine called when
|
|
the operation has been completed.
|
|
|
|
lpThreadId - A pointer to a thread ID structure to be used by the
|
|
provider in a subsequent call to WPUQueueApc(). The provider
|
|
should store the referenced WSATHREADID structure (not the pointer
|
|
to same) until after the WPUQueueApc() function returns.
|
|
|
|
lpErrno - A pointer to the error code.
|
|
|
|
Return Value:
|
|
|
|
If no error occurs and the operation has completed immediately, WSPIoctl()
|
|
returns 0. Note that in this case the completion routine, if specified,
|
|
will have already been queued. Otherwise, a value of SOCKET_ERROR is
|
|
returned, and a specific error code is available in lpErrno. The error
|
|
code WSA_IO_PENDING indicates that an overlapped operation has been
|
|
successfully initiated and that completion will be indicated at a later
|
|
time. Any other error code indicates that no overlapped operation was
|
|
initiated and no completion indication will occur.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
} // WSPIoctl
|
|
|
|
|
|
SOCKET
|
|
WSPAPI
|
|
WSPJoinLeaf(
|
|
IN SOCKET s,
|
|
IN const struct sockaddr FAR * name,
|
|
IN int namelen,
|
|
IN LPWSABUF lpCallerData,
|
|
OUT LPWSABUF lpCalleeData,
|
|
IN LPQOS lpSQOS,
|
|
IN LPQOS lpGQOS,
|
|
IN DWORD dwFlags,
|
|
OUT LPINT lpErrno
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is used to join a leaf node to a multipoint session, and to
|
|
perform a number of other ancillary operations that occur at session join
|
|
time as well. If the socket, s, is unbound, unique values are assigned to
|
|
the local association by the system, and the socket is marked as bound.
|
|
|
|
WSPJoinLeaf() has the same parameters and semantics as WSPConnect() except
|
|
that it returns a socket descriptor (as in WSPAccept()), and it has an
|
|
additional dwFlags parameter. Only multipoint sockets created using
|
|
WSPSocket() with appropriate multipoint flags set may be used for input
|
|
parameter s in this routine. If the socket is in the non-blocking mode,
|
|
the returned socket descriptor will not be useable until after a
|
|
corresponding FD_CONNECT indication has been received, except that
|
|
closesocket() may be invoked on this socket descriptor to cancel a pending
|
|
join operation. A root node in a multipoint session may call WSPJoinLeaf()
|
|
one or more times in order to add a number of leaf nodes, however at most
|
|
one multipoint connection request may be outstanding at a time. Refer to
|
|
section 3.14. Protocol-Independent Multicast and Multipoint for additional
|
|
information.
|
|
|
|
The socket descriptor returned by WSPJoinLeaf() is different depending on
|
|
whether the input socket descriptor, s, is a c_root or a c_leaf. When used
|
|
with a c_root socket, the name parameter designates a particular leaf node
|
|
to be added and the returned socket descriptor is a c_leaf socket
|
|
corresponding to the newly added leaf node. The newly created socket has
|
|
the same properties as s including asynchronous events registered with
|
|
WSPAsyncSelect() or with WSPEventSelect(), but not including the c_root
|
|
socket's group ID, if any. It is not intended to be used for exchange of
|
|
multipoint data, but rather is used to receive network event indications
|
|
(e.g. FD_CLOSE) for the connection that exists to the particular c_leaf.
|
|
Some multipoint implementations may also allow this socket to be used for
|
|
"side chats" between the root and an individual leaf node. An FD_CLOSE
|
|
indication will be received for this socket if the corresponding leaf node
|
|
calls WSPCloseSocket() to drop out of the multipoint session.
|
|
Symmetrically, invoking WSPCloseSocket() on the c_leaf socket returned from
|
|
WSPJoinLeaf() will cause the socket in the corresponding leaf node to get
|
|
FD_CLOSE notification.
|
|
|
|
When WSPJoinLeaf() is invoked with a c_leaf socket, the name parameter
|
|
contains the address of the root node (for a rooted control scheme) or an
|
|
existing multipoint session (non-rooted control scheme), and the returned
|
|
socket descriptor is the same as the input socket descriptor. In other
|
|
words, a new socket descriptor is not allocated. In a rooted control
|
|
scheme, the root application would put its c_root socket in the listening
|
|
mode by calling WSPListen(). The standard FD_ACCEPT notification will be
|
|
delivered when the leaf node requests to join itself to the multipoint
|
|
session. The root application uses the usual WSPAccept() functions to
|
|
admit the new leaf node. The value returned from WSPAccept() is also a
|
|
c_leaf socket descriptor just like those returned from WSPJoinLeaf(). To
|
|
accommodate multipoint schemes that allow both root-initiated and leaf-
|
|
initiated joins, it is acceptable for a c_root socket that is already in
|
|
listening mode to be used as an input to WSPJoinLeaf().
|
|
|
|
The WinSock SPI client is responsible for allocating any memory space
|
|
pointed to directly or indirectly by any of the parameters it specifies.
|
|
|
|
The lpCallerData is a value parameter which contains any user data that is
|
|
to be sent along with the multipoint session join request. If lpCallerData
|
|
is NULL, no user data will be passed to the peer. The lpCalleeData is a
|
|
result parameter which will contain any user data passed back from the peer
|
|
as part of the multipoint session establishment. lpCalleeData->len
|
|
initially contains the length of the buffer allocated by the WinSock SPI
|
|
client and pointed to by lpCalleeData->buf. lpCalleeData->len will be set
|
|
to 0 if no user data has been passed back. The lpCalleeData information
|
|
will be valid when the multipoint join operation is complete. For blocking
|
|
sockets, this will be when the WSPJoinLeaf() function returns. For non-
|
|
blocking sockets, this will be after the FD_CONNECT notification has
|
|
occurred. If lpCalleeData is NULL, no user data will be passed back. The
|
|
exact format of the user data is specific to the address family to which
|
|
the socket belongs and/or the applications involved.
|
|
|
|
At multipoint session establishment time, a WinSock SPI client may use the
|
|
lpSQOS and/or lpGQOS parameters to override any previous QOS specification
|
|
made for the socket via WSPIoctl() with either the SIO_SET_QOS or
|
|
SIO_SET_GROUP_QOS opcodes.
|
|
|
|
lpSQOS specifies the flow specs for socket s, one for each direction,
|
|
followed by any additional provider-specific parameters. If either the
|
|
associated transport provider in general or the specific type of socket in
|
|
particular cannot honor the QOS request, an error will be returned as
|
|
indicated below. The sending or receiving flow spec values will be ignored,
|
|
respectively, for any unidirectional sockets. If no provider-specific
|
|
parameters are supplied, the buf and len fields of lpSQOS->ProviderSpecific
|
|
should be set to NULL and 0, respectively. A NULL value for lpSQOS
|
|
indicates no application supplied QOS.
|
|
|
|
lpGQOS specifies the flow specs for the socket group (if applicable), one
|
|
for each direction, followed by any additional provider-specific
|
|
parameters. If no provider- specific parameters are supplied, the buf and
|
|
len fields of lpSQOS->ProviderSpecific should be set to NULL and 0,
|
|
respectively. A NULL value for lpGQOS indicates no application-supplied
|
|
group QOS. This parameter will be ignored if s is not the creator of the
|
|
socket group.
|
|
|
|
The dwFlags parameter is used to indicate whether the socket will be acting
|
|
only as a sender (JL_SENDER_ONLY), only as a receiver (JL_RECEIVER_ONLY),
|
|
or both (JL_BOTH).
|
|
|
|
When connected sockets break (i.e. become closed for whatever reason), they
|
|
should be discarded and recreated. It is safest to assume that when things
|
|
go awry for any reason on a connected socket, the WinSock SPI client must
|
|
discard and recreate the needed sockets in order to return to a stable
|
|
point.
|
|
|
|
Arguments:
|
|
|
|
s - A descriptor identifying a multipoint socket.
|
|
|
|
name - The name of the peer to which the socket is to be joined.
|
|
|
|
namelen - The length of the name.
|
|
|
|
lpCallerData - A pointer to the user data that is to be transferred to
|
|
the peer during multipoint session establishment.
|
|
|
|
lpCalleeData - A pointer to the user data that is to be transferred back
|
|
from the peer during multipoint session establishment.
|
|
|
|
lpSQOS - A pointer to the flow specs for socket s, one for each direction.
|
|
|
|
lpGQOS - A pointer to the flow specs for the socket group (if applicable).
|
|
|
|
dwFlags - Flags to indicate that the socket is acting as a sender,
|
|
receiver, or both.
|
|
|
|
lpErrno - A pointer to the error code.
|
|
|
|
Return Value:
|
|
|
|
If no error occurs, WSPJoinLeaf() returns a value of type SOCKET which is
|
|
a descriptor for the newly created multipoint socket. Otherwise, a
|
|
value of INVALID_SOCKET is returned, and a specific error code is
|
|
available in lpErrno.
|
|
|
|
On a blocking socket, the return value indicates success or failure of
|
|
the join operation.
|
|
|
|
With a non-blocking socket, successful initiation of a join operation
|
|
is indicated by a return value of a valid socket descriptor.
|
|
Subsequently, an FD_CONNECT indication is given when the join
|
|
operation completes, either successfully or otherwise.
|
|
|
|
Also, until the multipoint session join attempt completes all
|
|
subsequent calls to WSPJoinLeaf() on the same socket will fail with
|
|
the error code WSAEALREADY.
|
|
|
|
If the return error code indicates the multipoint session join attempt
|
|
failed (i.e. WSAECONNREFUSED, WSAENETUNREACH, WSAETIMEDOUT) the
|
|
WinSock SPI client may call WSPJoinLeaf() again for the same socket.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
} // WSPJoinLeaf
|
|
|
|
|
|
INT
|
|
WSPAPI
|
|
WSPListen(
|
|
IN SOCKET s,
|
|
IN int backlog,
|
|
OUT LPINT lpErrno
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
To accept connections, a socket is first created with WSPSocket(), a
|
|
backlog for incoming connections is specified with WSPListen(), and then
|
|
the connections are accepted with WSPAccept. WSPListen() applies only to
|
|
sockets that are connection-oriented (e.g., SOCK_STREAM). The socket s is
|
|
put into "passive'' mode where incoming connection requests are
|
|
acknowledged and queued pending acceptance by the WinSock SPI client.
|
|
|
|
This routine is typically used by servers that could have more than one
|
|
connection request at a time: if a connection request arrives with the
|
|
queue full, the client will receive an error with an indication of
|
|
WSAECONNREFUSED.
|
|
|
|
WSPListen() should continue to function rationally when there are no
|
|
available descriptors. It should accept connections until the queue is
|
|
emptied. If descriptors become available, a later call to WSPListen() or
|
|
WSPAccept() will re-fill the queue to the current or most recent "backlog",
|
|
if possible, and resume listening for incoming connections.
|
|
|
|
A WinSock SPI client may call WSPListen() more than once on the same
|
|
socket. This has the effect of updating the current backlog for the
|
|
listening socket. Should there be more pending connections than the new
|
|
backlog value, the excess pending connections will be reset and dropped.
|
|
|
|
Backlog is limited (silently) to a reasonable value as determined by the
|
|
service provider. Illegal values are replaced by the nearest legal value.
|
|
|
|
Arguments:
|
|
|
|
s - A descriptor identifying a bound, unconnected socket.
|
|
|
|
backlog - The maximum length to which the queue of pending connections
|
|
may grow. If this value is SOMAXCONN, then the service provider
|
|
should set the backlog to a maximum "reasonable" value.
|
|
|
|
lpErrno - A pointer to the error code.
|
|
|
|
Return Value:
|
|
|
|
If no error occurs, WSPListen() returns 0. Otherwise, a value of
|
|
SOCKET_ERROR is returned, and a specific error code is available
|
|
in lpErrno.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
} // WSPListen
|
|
|
|
|
|
INT
|
|
WSPAPI
|
|
WSPRecv(
|
|
IN SOCKET s,
|
|
IN OUT LPWSABUF lpBuffers,
|
|
IN DWORD dwBufferCount,
|
|
OUT LPDWORD lpNumberOfBytesRecvd,
|
|
IN OUT LPDWORD lpFlags,
|
|
IN LPWSAOVERLAPPED lpOverlapped,
|
|
IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
|
|
IN LPWSATHREADID lpThreadId,
|
|
OUT LPINT lpErrno
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is used on connected sockets or bound connectionless sockets
|
|
specified by the s parameter and is used to read incoming data.
|
|
|
|
For overlapped sockets WSPRecv() is used to post one or more buffers into
|
|
which incoming data will be placed as it becomes available, after which the
|
|
WinSock SPI client-specified completion indication (invocation of the
|
|
completion routine or setting of an event object) occurs. If the operation
|
|
does not complete immediately, the final completion status is retrieved
|
|
via the completion routine or WSPGetOverlappedResult().
|
|
|
|
If both lpOverlapped and lpCompletionRoutine are NULL, the socket in this
|
|
routine will be treated as a non-overlapped socket.
|
|
|
|
For non-overlapped sockets, the lpOverlapped, lpCompletionRoutine, and
|
|
lpThreadId parameters are ignored. Any data which has already been received
|
|
and buffered by the transport will be copied into the supplied user
|
|
buffers. For the case of a blocking socket with no data currently having
|
|
been received and buffered by the transport, the call will block until data
|
|
is received.
|
|
|
|
The supplied buffers are filled in the order in which they appear in the
|
|
array pointed to by lpBuffers, and the buffers are packed so that no holes
|
|
are created.
|
|
|
|
The array of WSABUF structures pointed to by the lpBuffers parameter is
|
|
transient. If this operation completes in an overlapped manner, it is the
|
|
service provider's responsibility to capture this array of pointers to
|
|
WSABUF structures before returning from this call. This enables WinSock SPI
|
|
clients to build stack-based WSABUF arrays.
|
|
|
|
For byte stream style sockets (e.g., type SOCK_STREAM), incoming data is
|
|
placed into the buffers until the buffers are filled, the connection is
|
|
closed, or internally buffered data is exhausted. Regardless of whether or
|
|
not the incoming data fills all the buffers, the completion indication
|
|
occurs for overlapped sockets. For message-oriented sockets (e.g., type
|
|
SOCK_DGRAM), an incoming message is placed into the supplied buffers, up
|
|
to the total size of the buffers supplied, and the completion indication
|
|
occurs for overlapped sockets. If the message is larger than the buffers
|
|
supplied, the buffers are filled with the first part of the message. If the
|
|
MSG_PARTIAL feature is supported by the service provider, the MSG_PARTIAL
|
|
flag is set in lpFlags and subsequent receive operation(s) may be used to
|
|
retrieve the rest of the message. If MSG_PARTIAL is not supported but the
|
|
protocol is reliable, WSPRecv() generates the error WSAEMSGSIZE and a
|
|
subsequent receive operation with a larger buffer can be used to retrieve
|
|
the entire message. Otherwise (i.e. the protocol is unreliable and does not
|
|
support MSG_PARTIAL), the excess data is lost, and WSPRecv() generates the
|
|
error WSAEMSGSIZE.
|
|
|
|
For connection-oriented sockets, WSPRecv() can indicate the graceful
|
|
termination of the virtual circuit in one of two ways, depending on whether
|
|
the socket is a byte stream or message-oriented. For byte streams, zero
|
|
bytes having been read indicates graceful closure and that no more bytes
|
|
will ever be read. For message-oriented sockets, where a zero byte message
|
|
is often allowable, a return error code of WSAEDISCON is used to indicate
|
|
graceful closure. In any case a return error code of WSAECONNRESET
|
|
indicates an abortive close has occurred.
|
|
|
|
lpFlags may be used to influence the behavior of the function invocation
|
|
beyond the options specified for the associated socket. That is, the
|
|
semantics of this routine are determined by the socket options and the
|
|
lpFlags parameter. The latter is constructed by or-ing any of the
|
|
following values:
|
|
|
|
MSG_PEEK - Peek at the incoming data. The data is copied into the
|
|
buffer but is not removed from the input queue. This flag is valid
|
|
only for non-overlapped sockets.
|
|
|
|
MSG_OOB - Process out-of-band data.
|
|
|
|
MSG_PARTIAL - This flag is for message-oriented sockets only. On
|
|
output, indicates that the data supplied is a portion of the message
|
|
transmitted by the sender. Remaining portions of the message will be
|
|
supplied in subsequent receive operations. A subsequent receive
|
|
operation with MSG_PARTIAL flag cleared indicates end of sender's
|
|
message.
|
|
|
|
As an input parameter, MSG_PARTIAL indicates that the receive
|
|
operation should complete even if only part of a message has been
|
|
received by the service provider.
|
|
|
|
If an overlapped operation completes immediately, WSPRecv() returns a
|
|
value of zero and the lpNumberOfBytesRecvd parameter is updated with the
|
|
number of bytes received. If the overlapped operation is successfully
|
|
initiated and will complete later, WSPRecv() returns SOCKET_ERROR and
|
|
indicates error code WSA_IO_PENDING. In this case, lpNumberOfBytesRecvd is
|
|
not updated. When the overlapped operation completes the amount of data
|
|
transferred is indicated either via the cbTransferred parameter in the
|
|
completion routine (if specified), or via the lpcbTransfer parameter in
|
|
WSPGetOverlappedResult().
|
|
|
|
Providers must allow this routine to be called from within the completion
|
|
routine of a previous WSPRecv(), WSPRecvFrom(), WSPSend() or WSPSendTo()
|
|
function. However, for a given socket, I/O completion routines may not be
|
|
nested. This permits time-sensitive data transmissions to occur entirely
|
|
within a preemptive context.
|
|
|
|
The lpOverlapped parameter must be valid for the duration of the
|
|
overlapped operation. If multiple I/O operations are simultaneously
|
|
outstanding, each must reference a separate overlapped structure. The
|
|
WSAOVERLAPPED structure has the following form:
|
|
|
|
typedef struct _WSAOVERLAPPED {
|
|
DWORD Internal; // reserved
|
|
DWORD InternalHigh; // reserved
|
|
DWORD Offset; // reserved
|
|
DWORD OffsetHigh; // reserved
|
|
WSAEVENT hEvent;
|
|
} WSAOVERLAPPED, FAR * LPWSAOVERLAPPED;
|
|
|
|
If the lpCompletionRoutine parameter is NULL, the service provider signals
|
|
the hEvent field of lpOverlapped when the overlapped operation completes
|
|
if it contains a valid event object handle. The WinSock SPI client can use
|
|
WSPGetOverlappedResult() to wait or poll on the event object.
|
|
|
|
If lpCompletionRoutine is not NULL, the hEvent field is ignored and can be
|
|
used by the WinSock SPI client to pass context information to the
|
|
completion routine. It is the service provider's responsibility to arrange
|
|
for invocation of the client-specified completion routine when the
|
|
overlapped operation completes. Since the completion routine must be
|
|
executed in the context of the same thread that initiated the overlapped
|
|
operation, it cannot be invoked directly from the service provider. The
|
|
WinSock DLL offers an asynchronous procedure call (APC) mechanism to
|
|
facilitate invocation of completion routines.
|
|
|
|
A service provider arranges for a function to be executed in the proper
|
|
thread by calling WPUQueueApc(). Note that this routine must be invoked
|
|
while in the context of the same process (but not necessarily the same
|
|
thread) that was used to initiate the overlapped operation. It is the
|
|
service provider's responsibility to arrange for this process context to
|
|
be active prior to calling WPUQueueApc().
|
|
|
|
WPUQueueApc() takes as input parameters a pointer to a WSATHREADID
|
|
structure (supplied to the provider via the lpThreadId input parameter),
|
|
a pointer to an APC function to be invoked, and a 32 bit context value
|
|
that is subsequently passed to the APC function. Because only a single
|
|
32-bit context value is available, the APC function cannot itself be the
|
|
client-specified completion routine. The service provider must instead
|
|
supply a pointer to its own APC function which uses the supplied context
|
|
value to access the needed result information for the overlapped operation,
|
|
and then invokes the client-specified completion routine.
|
|
|
|
The prototype for the client-supplied completion routine is as follows:
|
|
|
|
void
|
|
CALLBACK
|
|
CompletionRoutine(
|
|
IN DWORD dwError,
|
|
IN DWORD cbTransferred,
|
|
IN LPWSAOVERLAPPED lpOverlapped,
|
|
IN DWORD dwFlags
|
|
);
|
|
|
|
CompletionRoutine is a placeholder for a client supplied function
|
|
name.
|
|
|
|
dwError specifies the completion status for the overlapped
|
|
operation as indicated by lpOverlapped.
|
|
|
|
cbTransferred specifies the number of bytes sent.
|
|
|
|
No flag values are currently defined and the dwFlags value will
|
|
be zero.
|
|
|
|
This routine does not return a value.
|
|
|
|
The completion routines may be called in any order, not necessarily in
|
|
the same order the overlapped operations are completed. However, the
|
|
posted buffers are guaranteed to be filled in the same order they are
|
|
supplied.
|
|
|
|
Arguments:
|
|
|
|
s - A descriptor identifying a connected socket.
|
|
|
|
lpBuffers - A pointer to an array of WSABUF structures. Each WSABUF
|
|
structure contains a pointer to a buffer and the length of the
|
|
buffer.
|
|
|
|
dwBufferCount - The number of WSABUF structures in the lpBuffers
|
|
array.
|
|
|
|
lpNumberOfBytesRecvd - A pointer to the number of bytes received by
|
|
this call.
|
|
|
|
lpFlags - A pointer to flags.
|
|
|
|
lpOverlapped - A pointer to a WSAOVERLAPPED structure.
|
|
|
|
lpCompletionRoutine - A pointer to the completion routine called when
|
|
the receive operation has been completed.
|
|
|
|
lpThreadId - A pointer to a thread ID structure to be used by the
|
|
provider in a subsequent call to WPUQueueApc(). The provider should
|
|
store the referenced WSATHREADID structure (not the pointer to same)
|
|
until after the WPUQueueApc() function returns.
|
|
|
|
lpErrno - A pointer to the error code.
|
|
|
|
Return Value:
|
|
|
|
If no error occurs and the receive operation has completed immediately,
|
|
WSPRecv() returns 0. Note that in this case the completion routine,
|
|
if specified, will have already been queued. Otherwise, a value of
|
|
SOCKET_ERROR is returned, and a specific error code is available in
|
|
lpErrno. The error code WSA_IO_PENDING indicates that the overlapped
|
|
operation has been successfully initiated and that completion will be
|
|
indicated at a later time. Any other error code indicates that no
|
|
overlapped operations was initiated and no completion indication will
|
|
occur.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
} // WSPRecv
|
|
|
|
|
|
INT
|
|
WSPAPI
|
|
WSPRecvDisconnect(
|
|
IN SOCKET s,
|
|
OUT LPWSABUF lpInboundDisconnectData,
|
|
OUT LPINT lpErrno
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is used on connection-oriented sockets to disable reception,
|
|
and retrieve any incoming disconnect data from the remote party.
|
|
|
|
After this routine has been successfully issued, subsequent receives on the
|
|
socket will be disallowed. This has no effect on the lower protocol layers.
|
|
For TCP, the TCP window is not changed and incoming data will be accepted
|
|
(but not acknowledged) until the window is exhausted. For UDP, incoming
|
|
datagrams are accepted and queued. In no case will an ICMP error packet be
|
|
generated.
|
|
|
|
To successfully receive incoming disconnect data, a WinSock SPI client must
|
|
use other mechanisms to determine that the circuit has been closed. For
|
|
example, a client needs to receive an FD_CLOSE notification, or get a 0
|
|
return value, or a WSAEDISCON error code from WSPRecv().
|
|
|
|
Note that WSPRecvDisconnect() does not close the socket, and resources
|
|
attached to the socket will not be freed until WSPCloseSocket() is invoked.
|
|
|
|
WSPRecvDisconnect() does not block regardless of the SO_LINGER setting on
|
|
the socket.
|
|
|
|
A WinSock SPI client should not rely on being able to re-use a socket after
|
|
it has been WSPRecvDisconnect()ed. In particular, a WinSock provider is not
|
|
required to support the use of WSPConnect() on such a socket.
|
|
|
|
Arguments:
|
|
|
|
s - A descriptor identifying a socket.
|
|
|
|
lpInboundDisconnectData - A pointer to a buffer into which disconnect
|
|
data is to be copied.
|
|
|
|
lpErrno - A pointer to the error code.
|
|
|
|
Return Value:
|
|
|
|
If no error occurs, WSPRecvDisconnect() returns 0. Otherwise, a value of
|
|
SOCKET_ERROR is returned, and a specific error code is available in
|
|
lpErrno.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
} // WSPRecvDisconnect
|
|
|
|
|
|
INT
|
|
WSPAPI
|
|
WSPRecvFrom(
|
|
IN SOCKET s,
|
|
IN OUT LPWSABUF lpBuffers,
|
|
IN DWORD dwBufferCount,
|
|
OUT LPDWORD lpNumberOfBytesRecvd,
|
|
IN OUT LPDWORD lpFlags,
|
|
OUT struct sockaddr FAR * lpFrom,
|
|
IN OUT LPINT lpFromlen,
|
|
IN LPWSAOVERLAPPED lpOverlapped,
|
|
IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
|
|
IN LPWSATHREADID lpThreadId,
|
|
OUT LPINT lpErrno
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is used primarily on a connectionless socket specified by s.
|
|
|
|
For overlapped sockets WSPRecv() is used to post one or more buffers into
|
|
which incoming data will be placed as it becomes available, after which the
|
|
WinSock SPI client-specified completion indication (invocation of the
|
|
completion routine or setting of an event object) occurs. If the operation
|
|
does not complete immediately, the final completion status is retrieved
|
|
via the completion routine or WSPGetOverlappedResult(). Also note that the
|
|
values pointed to by lpFrom and lpFromlen are not updated until completion
|
|
is indicated. Applications must not use or disturb these values until they
|
|
have been updated, therefore the client must not use automatic (i.e stack-
|
|
based) variables for these parameters.
|
|
|
|
If both lpOverlapped and lpCompletionRoutine are NULL, the socket in this
|
|
routine will be treated as a non-overlapped socket.
|
|
|
|
For non-overlapped sockets, the lpOverlapped, lpCompletionRoutine, and
|
|
lpThreadId parameters are ignored. Any data which has already been received
|
|
and buffered by the transport will be copied into the supplied user
|
|
buffers. For the case of a blocking socket with no data currently having
|
|
been received and buffered by the transport, the call will block until data
|
|
is received.
|
|
|
|
The supplied buffers are filled in the order in which they appear in the
|
|
array pointed to by lpBuffers, and the buffers are packed so that no holes
|
|
are created.
|
|
|
|
The array of WSABUF structures pointed to by the lpBuffers parameter is
|
|
transient. If this operation completes in an overlapped manner, it is the
|
|
service provider's responsibility to capture this array of pointers to
|
|
WSABUF structures before returning from this call. This enables WinSock SPI
|
|
clients to build stack-based WSABUF arrays.
|
|
|
|
For connectionless socket types, the address from which the data originated
|
|
is copied to the buffer pointed by lpFrom. On input, the value pointed to
|
|
by lpFromlen is initialized to the size of this buffer, and is modified on
|
|
completion to indicate the actual size of the address stored there. As
|
|
noted previously for overlapped sockets, the lpFrom and lpFromlen
|
|
parameters are not updated until after the overlapped I/O has completed.
|
|
The memory pointed to by these parameters must, therefore, remain available
|
|
to the service provider and cannot be allocated on the WinSock SPI client's
|
|
stack frame. The lpFrom and lpFromlen parameters are ignored for
|
|
connection-oriented sockets.
|
|
|
|
For byte stream style sockets (e.g., type SOCK_STREAM), incoming data is
|
|
placed into the buffers until the buffers are filled, the connection is
|
|
closed, or internally buffered data is exhausted. Regardless of whether or
|
|
not the incoming data fills all the buffers, the completion indication
|
|
occurs for overlapped sockets. For message-oriented sockets (e.g., type
|
|
SOCK_DGRAM), an incoming message is placed into the supplied buffers, up
|
|
to the total size of the buffers supplied, and the completion indication
|
|
occurs for overlapped sockets. If the message is larger than the buffers
|
|
supplied, the buffers are filled with the first part of the message. If the
|
|
MSG_PARTIAL feature is supported by the service provider, the MSG_PARTIAL
|
|
flag is set in lpFlags and subsequent receive operation(s) may be used to
|
|
retrieve the rest of the message. If MSG_PARTIAL is not supported but the
|
|
protocol is reliable, WSPRecvFrom() generates the error WSAEMSGSIZE and a
|
|
subsequent receive operation with a larger buffer can be used to retrieve
|
|
the entire message. Otherwise (i.e. the protocol is unreliable and does not
|
|
support MSG_PARTIAL), the excess data is lost, and WSPRecvFrom() generates
|
|
the error WSAEMSGSIZE.
|
|
|
|
For connection-oriented sockets, WSPRecvFrom() can indicate the graceful
|
|
termination of the virtual circuit in one of two ways, depending on whether
|
|
the socket is a byte stream or message-oriented. For byte streams, zero
|
|
bytes having been read indicates graceful closure and that no more bytes
|
|
will ever be read. For message-oriented sockets, where a zero byte message
|
|
is often allowable, a return error code of WSAEDISCON is used to indicate
|
|
graceful closure. In any case a return error code of WSAECONNRESET
|
|
indicates an abortive close has occurred.
|
|
|
|
lpFlags may be used to influence the behavior of the function invocation
|
|
beyond the options specified for the associated socket. That is, the
|
|
semantics of this routine are determined by the socket options and the
|
|
lpFlags parameter. The latter is constructed by or-ing any of the
|
|
following values:
|
|
|
|
MSG_PEEK - Peek at the incoming data. The data is copied into the
|
|
buffer but is not removed from the input queue. This flag is valid
|
|
only for non-overlapped sockets.
|
|
|
|
MSG_OOB - Process out-of-band data.
|
|
|
|
MSG_PARTIAL - This flag is for message-oriented sockets only. On
|
|
output, indicates that the data supplied is a portion of the message
|
|
transmitted by the sender. Remaining portions of the message will be
|
|
supplied in subsequent receive operations. A subsequent receive
|
|
operation with MSG_PARTIAL flag cleared indicates end of sender's
|
|
message.
|
|
|
|
As an input parameter, MSG_PARTIAL indicates that the receive
|
|
operation should complete even if only part of a message has been
|
|
received by the service provider.
|
|
|
|
For message-oriented sockets, the MSG_PARTIAL bit is set in the lpFlags
|
|
parameter if a partial message is received. If a complete message is
|
|
received, MSG_PARTIAL is cleared in lpFlags. In the case of delayed
|
|
completion, the value pointed to by lpFlags is not updated. When
|
|
completion has been indicated the WinSock SPI client should call
|
|
WSPGetOverlappedResult() and examine the flags pointed to by the
|
|
lpdwFlags parameter.
|
|
|
|
If an overlapped operation completes immediately, WSPRecvFrom() returns a
|
|
value of zero and the lpNumberOfBytesRecvd parameter is updated with the
|
|
number of bytes received. If the overlapped operation is successfully
|
|
initiated and will complete later, WSPRecvFrom() returns SOCKET_ERROR and
|
|
indicates error code WSA_IO_PENDING. In this case, lpNumberOfBytesRecvd is
|
|
not updated. When the overlapped operation completes the amount of data
|
|
transferred is indicated either via the cbTransferred parameter in the
|
|
completion routine (if specified), or via the lpcbTransfer parameter in
|
|
WSPGetOverlappedResult().
|
|
|
|
Providers must allow this routine to be called from within the completion
|
|
routine of a previous WSPRecv(), WSPRecvFrom(), WSPSend() or WSPSendTo()
|
|
function. However, for a given socket, I/O completion routines may not be
|
|
nested. This permits time-sensitive data transmissions to occur entirely
|
|
within a preemptive context.
|
|
|
|
The lpOverlapped parameter must be valid for the duration of the
|
|
overlapped operation. If multiple I/O operations are simultaneously
|
|
outstanding, each must reference a separate overlapped structure. The
|
|
WSAOVERLAPPED structure has the following form:
|
|
|
|
typedef struct _WSAOVERLAPPED {
|
|
DWORD Internal; // reserved
|
|
DWORD InternalHigh; // reserved
|
|
DWORD Offset; // reserved
|
|
DWORD OffsetHigh; // reserved
|
|
WSAEVENT hEvent;
|
|
} WSAOVERLAPPED, FAR * LPWSAOVERLAPPED;
|
|
|
|
If the lpCompletionRoutine parameter is NULL, the service provider signals
|
|
the hEvent field of lpOverlapped when the overlapped operation completes
|
|
if it contains a valid event object handle. The WinSock SPI client can use
|
|
WSPGetOverlappedResult() to wait or poll on the event object.
|
|
|
|
If lpCompletionRoutine is not NULL, the hEvent field is ignored and can be
|
|
used by the WinSock SPI client to pass context information to the
|
|
completion routine. It is the service provider's responsibility to arrange
|
|
for invocation of the client-specified completion routine when the
|
|
overlapped operation completes. Since the completion routine must be
|
|
executed in the context of the same thread that initiated the overlapped
|
|
operation, it cannot be invoked directly from the service provider. The
|
|
WinSock DLL offers an asynchronous procedure call (APC) mechanism to
|
|
facilitate invocation of completion routines.
|
|
|
|
A service provider arranges for a function to be executed in the proper
|
|
thread by calling WPUQueueApc(). Note that this routine must be invoked
|
|
while in the context of the same process (but not necessarily the same
|
|
thread) that was used to initiate the overlapped operation. It is the
|
|
service provider's responsibility to arrange for this process context to
|
|
be active prior to calling WPUQueueApc().
|
|
|
|
WPUQueueApc() takes as input parameters a pointer to a WSATHREADID
|
|
structure (supplied to the provider via the lpThreadId input parameter),
|
|
a pointer to an APC function to be invoked, and a 32 bit context value
|
|
that is subsequently passed to the APC function. Because only a single
|
|
32-bit context value is available, the APC function cannot itself be the
|
|
client-specified completion routine. The service provider must instead
|
|
supply a pointer to its own APC function which uses the supplied context
|
|
value to access the needed result information for the overlapped operation,
|
|
and then invokes the client-specified completion routine.
|
|
|
|
The prototype for the client-supplied completion routine is as follows:
|
|
|
|
void
|
|
CALLBACK
|
|
CompletionRoutine(
|
|
IN DWORD dwError,
|
|
IN DWORD cbTransferred,
|
|
IN LPWSAOVERLAPPED lpOverlapped,
|
|
IN DWORD dwFlags
|
|
);
|
|
|
|
CompletionRoutine is a placeholder for a client supplied function
|
|
name.
|
|
|
|
dwError specifies the completion status for the overlapped
|
|
operation as indicated by lpOverlapped.
|
|
|
|
cbTransferred specifies the number of bytes sent.
|
|
|
|
No flag values are currently defined and the dwFlags value will
|
|
be zero.
|
|
|
|
This routine does not return a value.
|
|
|
|
The completion routines may be called in any order, not necessarily in
|
|
the same order the overlapped operations are completed. However, the
|
|
posted buffers are guaranteed to be filled in the same order they are
|
|
supplied.
|
|
|
|
Arguments:
|
|
|
|
s - A descriptor identifying a socket.
|
|
|
|
lpBuffers - A pointer to an array of WSABUF structures. Each WSABUF
|
|
structure contains a pointer to a buffer and the length of the
|
|
buffer.
|
|
|
|
dwBufferCount - The number of WSABUF structures in the lpBuffers array.
|
|
|
|
lpNumberOfBytesRecvd - A pointer to the number of bytes received by
|
|
this call.
|
|
|
|
lpFlags - A pointer to flags.
|
|
|
|
lpFrom - An optional pointer to a buffer which will hold the source
|
|
address upon the completion of the overlapped operation.
|
|
|
|
lpFromlen - A pointer to the size of the from buffer, required only if
|
|
lpFrom is specified.
|
|
|
|
lpOverlapped - A pointer to a WSAOVERLAPPED structure.
|
|
|
|
lpCompletionRoutine - A pointer to the completion routine called when
|
|
the receive operation has been completed.
|
|
|
|
lpThreadId - A pointer to a thread ID structure to be used by the
|
|
provider in a subsequent call to WPUQueueApc().The provider should
|
|
store the referenced WSATHREADID structure (not the pointer to same)
|
|
until after the WPUQueueApc() function returns.
|
|
|
|
lpErrno - A pointer to the error code.
|
|
|
|
Return Value:
|
|
|
|
If no error occurs and the receive operation has completed immediately,
|
|
WSPRecvFrom() returns 0. Note that in this case the completion routine,
|
|
if specified will have already been queued. Otherwise, a value of
|
|
SOCKET_ERROR is returned, and a specific error code is available in
|
|
lpErrno. The error code WSA_IO_PENDING indicates that the overlapped
|
|
operation has been successfully initiated and that completion will be
|
|
indicated at a later time. Any other error code indicates that no
|
|
overlapped operations was initiated and no completion indication will
|
|
occur.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
} // WSPRecvFrom
|
|
|
|
|
|
INT
|
|
WSPAPI
|
|
WSPSelect(
|
|
IN int nfds,
|
|
IN OUT fd_set FAR * readfds,
|
|
IN OUT fd_set FAR * writefds,
|
|
IN OUT fd_set FAR * exceptfds,
|
|
IN const struct timeval FAR * timeout,
|
|
OUT LPINT lpErrno
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is used to determine the status of one or more sockets. For
|
|
each socket, the caller may request information on read, write or error
|
|
status. The set of sockets for which a given status is requested is
|
|
indicated by an fd_set structure. All entries in an fd_set correspond to
|
|
sockets created by the service provider. Upon return, the structures are
|
|
updated to reflect the subset of these sockets which meet the specified
|
|
condition, and WSPSelect() returns the total number of sockets meeting the
|
|
conditions. A set of macros is provided for manipulating an fd_set. These
|
|
macros are compatible with those used in the Berkeley software, but the
|
|
underlying representation is completely different.
|
|
|
|
The parameter readfds identifies those sockets which are to be checked for
|
|
readability. If the socket is currently WSPListen()ing, it will be marked
|
|
as readable if an incoming connection request has been received, so that a
|
|
WSPAccept() is guaranteed to complete without blocking. For other sockets,
|
|
readability means that queued data is available for reading so that a
|
|
WSPRecv() or WSPRecvfrom() is guaranteed not to block.
|
|
|
|
For connection-oriented sockets, readability may also indicate that a close
|
|
request has been received from the peer. If the virtual circuit was
|
|
closed gracefully, then a WSPRecv() will return immediately with 0 bytes
|
|
read. If the virtual circuit was reset, then a WSPRecv() will complete
|
|
immediately with an error code, such as WSAECONNRESET. The presence of
|
|
out-of-band data will be checked if the socket option SO_OOBINLINE has
|
|
been enabled (see WSPSetSockOpt()).
|
|
|
|
The parameter writefds identifies those sockets which are to be checked for
|
|
writability. If a socket is WSPConnect()ing, writability means that the
|
|
connection establishment successfully completed. If the socket is not in
|
|
the process of WSPConnect()ing, writability means that a WSPSend() or
|
|
WSPSendTo() are guaranteed to succeed. However, they may block on a
|
|
blocking socket if the len exceeds the amount of outgoing system buffer
|
|
space available.. (It is not specified how long these guarantees can be
|
|
assumed to be valid, particularly in a multithreaded environment.)
|
|
|
|
The parameter exceptfds identifies those sockets which are to be checked
|
|
for the presence of out-of-band data or any exceptional error conditions.
|
|
Note that out-of-band data will only be reported in this way if the option
|
|
SO_OOBINLINE is FALSE. If a socket is WSPConnect()ing (non-blocking),
|
|
failure of the connect attempt is indicated in exceptfds.
|
|
|
|
Any two of readfds, writefds, or exceptfds may be given as NULL if no
|
|
descriptors are to be checked for the condition of interest. At least one
|
|
must be non-NULL, and any non- NULL descriptor set must contain at least
|
|
one socket descriptor.
|
|
|
|
A socket will be identified in a particular set when WSPSelect() returns
|
|
if:
|
|
|
|
readfds
|
|
~~~~~~~
|
|
|
|
If WSPListen()ing, a connection is pending, WSPAccept()
|
|
will succeed.
|
|
|
|
Data is available for reading (includes OOB data if
|
|
SO_OOBINLINE is enabled).
|
|
|
|
Connection has been closed/reset/aborted.
|
|
|
|
writefds
|
|
~~~~~~~~
|
|
|
|
If WSPConnect()ing (non-blocking), connection has succeeded.
|
|
|
|
Data may be sent.
|
|
|
|
|
|
exceptfds
|
|
~~~~~~~~~
|
|
|
|
If WSPConnect()ing (non-blocking), connection attempt failed.
|
|
|
|
OOB data is available for reading (only if SO_OOBINLINE is
|
|
disabled).
|
|
|
|
Three macros and one upcall function are defined in the header file
|
|
ws2spi.h for manipulating and checking the descriptor sets. The variable
|
|
FD_SETSIZE determines the maximum number of descriptors in a set. (The
|
|
default value of FD_SETSIZE is 64, which may be modified by #defining
|
|
FD_SETSIZE to another value before #including ws2spi.h.) Internally,
|
|
socket handles in a fd_set are not represented as bit flags as in Berkeley
|
|
Unix. Their data representation is opaque. Use of these macros will
|
|
maintain software portability between different socket environments. The
|
|
macros to manipulate and check fd_set contents are:
|
|
|
|
FD_CLR(s, *set) Removes the descriptor s from set.
|
|
|
|
FD_SET(s, *set) Adds descriptor s to set.
|
|
|
|
FD_ZERO(*set) Initializes the set to the NULL set.
|
|
|
|
The upcall function used to check the membership is:
|
|
|
|
int WPUFDIsSet ( SOCKET s, FD_SET FAR * set );
|
|
|
|
which will return nonzero if s is a member of the set, or zero otherwise.
|
|
|
|
The parameter timeout controls how long the WSPSelect() may take to
|
|
complete. If timeout is a null pointer, WSPSelect() will block indefinitely
|
|
until at least one descriptor meets the specified criteria. Otherwise,
|
|
timeout points to a struct timeval which specifies the maximum time that
|
|
WSPSelect() should wait before returning. When WSPSelect() returns, the
|
|
contents of the struct timeval are not altered. If the timeval is
|
|
initialized to {0, 0}, WSPSelect() will return immediately; this is used
|
|
to "poll" the state of the selected sockets. If this is the case, then the
|
|
WSPSelect() call is considered nonblocking and the standard assumptions for
|
|
nonblocking calls apply. For example, the blocking hook will not be called,
|
|
and the WinSock provider will not yield.
|
|
|
|
WSPSelect() has no effect on the persistence of socket events registered
|
|
with WSPAsyncSelect() or WSPEventSelect().
|
|
|
|
Arguments:
|
|
|
|
nfds - This argument is ignored and included only for the sake of
|
|
compatibility.
|
|
|
|
readfds - An optional pointer to a set of sockets to be checked for
|
|
readability.
|
|
|
|
writefds - An optional pointer to a set of sockets to be checked for
|
|
writability
|
|
|
|
exceptfds - An optional pointer to a set of sockets to be checked for
|
|
errors.
|
|
|
|
timeout - The maximum time for WSPSelect() to wait, or NULL for a
|
|
blocking operation.
|
|
|
|
lpErrno - A pointer to the error code.
|
|
|
|
Return Value:
|
|
|
|
WSPSelect() returns the total number of descriptors which are ready and
|
|
contained in the fd_set structures, or SOCKET_ERROR if an error
|
|
occurred. If the return value is SOCKET_ERROR, a specific error code
|
|
is available in lpErrno.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
} // WSPSelect
|
|
|
|
|
|
INT
|
|
WSPAPI
|
|
WSPSend(
|
|
IN SOCKET s,
|
|
IN LPWSABUF lpBuffers,
|
|
IN DWORD dwBufferCount,
|
|
OUT LPDWORD lpNumberOfBytesSent,
|
|
IN DWORD dwFlags,
|
|
IN LPWSAOVERLAPPED lpOverlapped,
|
|
IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
|
|
IN LPWSATHREADID lpThreadId,
|
|
OUT LPINT lpErrno
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is used to write outgoing data from one or more buffers on a
|
|
connection-oriented socket specified by s. It may also be used, however,
|
|
on connectionless sockets which have a stipulated default peer address
|
|
established via the WSPConnect() function.
|
|
|
|
For overlapped sockets (created using WSPSocket() with flag
|
|
WSA_FLAG_OVERLAPPED) this will occur using overlapped I/O, unless both
|
|
lpOverlapped and lpCompletionRoutine are NULL in which case the socket is
|
|
treated as a non-overlapped socket. A completion indication will occur
|
|
(invocation of the completion routine or setting of an event object) when
|
|
the supplied buffer(s) have been consumed by the transport. If the
|
|
operation does not complete immediately, the final completion status is
|
|
retrieved via the completion routine or WSPGetOverlappedResult().
|
|
|
|
For non-overlapped sockets, the parameters lpOverlapped,
|
|
lpCompletionRoutine, and lpThreadId are ignored and WSPSend() adopts the
|
|
regular synchronous semantics. Data is copied from the supplied buffer(s)
|
|
into the transport's buffer. If the socket is non-blocking and stream-
|
|
oriented, and there is not sufficient space in the transport's buffer,
|
|
WSPSend() will return with only part of the supplied buffers having been
|
|
consumed. Given the same buffer situation and a blocking socket, WSPSend()
|
|
will block until all of the supplied buffer contents have been consumed.
|
|
|
|
The array of WSABUF structures pointed to by the lpBuffers parameter is
|
|
transient. If this operation completes in an overlapped manner, it is the
|
|
service provider's responsibility to capture these WSABUF structures
|
|
before returning from this call. This enables applications to build stack-
|
|
based WSABUF arrays.
|
|
|
|
For message-oriented sockets, care must be taken not to exceed the maximum
|
|
message size of the underlying provider, which can be obtained by getting
|
|
the value of socket option SO_MAX_MSG_SIZE. If the data is too long to
|
|
pass atomically through the underlying protocol the error WSAEMSGSIZE is
|
|
returned, and no data is transmitted.
|
|
|
|
Note that the successful completion of a WSPSend() does not indicate that
|
|
the data was successfully delivered.
|
|
|
|
dwFlags may be used to influence the behavior of the function invocation
|
|
beyond the options specified for the associated socket. That is, the
|
|
semantics of this routine are determined by the socket options and the
|
|
dwFlags parameter. The latter is constructed by or-ing any of the
|
|
following values:
|
|
|
|
MSG_DONTROUTE - Specifies that the data should not be subject
|
|
to routing. A WinSock service provider may choose to ignore this
|
|
flag.
|
|
|
|
MSG_OOB - Send out-of-band data (stream style socket such as
|
|
SOCK_STREAM only).
|
|
|
|
MSG_PARTIAL - Specifies that lpBuffers only contains a partial
|
|
message. Note that the error code WSAEOPNOTSUPP will be returned
|
|
which do not support partial message transmissions.
|
|
|
|
If an overlapped operation completes immediately, WSPSend() returns a
|
|
value of zero and the lpNumberOfBytesSent parameter is updated with the
|
|
number of bytes sent. If the overlapped operation is successfully
|
|
initiated and will complete later, WSPSend() returns SOCKET_ERROR and
|
|
indicates error code WSA_IO_PENDING. In this case, lpNumberOfBytesSent is
|
|
not updated. When the overlapped operation completes the amount of data
|
|
transferred is indicated either via the cbTransferred parameter in the
|
|
completion routine (if specified), or via the lpcbTransfer parameter in
|
|
WSPGetOverlappedResult().
|
|
|
|
Providers must allow this routine to be called from within the completion
|
|
routine of a previous WSPRecv(), WSPRecvFrom(), WSPSend() or WSPSendTo()
|
|
function. However, for a given socket, I/O completion routines may not be
|
|
nested. This permits time-sensitive data transmissions to occur entirely
|
|
within a preemptive context.
|
|
|
|
The lpOverlapped parameter must be valid for the duration of the
|
|
overlapped operation. If multiple I/O operations are simultaneously
|
|
outstanding, each must reference a separate overlapped structure. The
|
|
WSAOVERLAPPED structure has the following form:
|
|
|
|
typedef struct _WSAOVERLAPPED {
|
|
DWORD Internal; // reserved
|
|
DWORD InternalHigh; // reserved
|
|
DWORD Offset; // reserved
|
|
DWORD OffsetHigh; // reserved
|
|
WSAEVENT hEvent;
|
|
} WSAOVERLAPPED, FAR * LPWSAOVERLAPPED;
|
|
|
|
If the lpCompletionRoutine parameter is NULL, the service provider signals
|
|
the hEvent field of lpOverlapped when the overlapped operation completes
|
|
if it contains a valid event object handle. The WinSock SPI client can use
|
|
WSPGetOverlappedResult() to wait or poll on the event object.
|
|
|
|
If lpCompletionRoutine is not NULL, the hEvent field is ignored and can be
|
|
used by the WinSock SPI client to pass context information to the
|
|
completion routine. It is the service provider's responsibility to arrange
|
|
for invocation of the client-specified completion routine when the
|
|
overlapped operation completes. Since the completion routine must be
|
|
executed in the context of the same thread that initiated the overlapped
|
|
operation, it cannot be invoked directly from the service provider. The
|
|
WinSock DLL offers an asynchronous procedure call (APC) mechanism to
|
|
facilitate invocation of completion routines.
|
|
|
|
A service provider arranges for a function to be executed in the proper
|
|
thread by calling WPUQueueApc(). Note that this routine must be invoked
|
|
while in the context of the same process (but not necessarily the same
|
|
thread) that was used to initiate the overlapped operation. It is the
|
|
service provider's responsibility to arrange for this process context to
|
|
be active prior to calling WPUQueueApc().
|
|
|
|
WPUQueueApc() takes as input parameters a pointer to a WSATHREADID
|
|
structure (supplied to the provider via the lpThreadId input parameter),
|
|
a pointer to an APC function to be invoked, and a 32 bit context value
|
|
that is subsequently passed to the APC function. Because only a single
|
|
32-bit context value is available, the APC function cannot itself be the
|
|
client-specified completion routine. The service provider must instead
|
|
supply a pointer to its own APC function which uses the supplied context
|
|
value to access the needed result information for the overlapped operation,
|
|
and then invokes the client-specified completion routine.
|
|
|
|
The prototype for the client-supplied completion routine is as follows:
|
|
|
|
void
|
|
CALLBACK
|
|
CompletionRoutine(
|
|
IN DWORD dwError,
|
|
IN DWORD cbTransferred,
|
|
IN LPWSAOVERLAPPED lpOverlapped,
|
|
IN DWORD dwFlags
|
|
);
|
|
|
|
CompletionRoutine is a placeholder for a client supplied function
|
|
name.
|
|
|
|
dwError specifies the completion status for the overlapped
|
|
operation as indicated by lpOverlapped.
|
|
|
|
cbTransferred specifies the number of bytes sent.
|
|
|
|
No flag values are currently defined and the dwFlags value will
|
|
be zero.
|
|
|
|
This routine does not return a value.
|
|
|
|
The completion routines may be called in any order, not necessarily in
|
|
the same order the overlapped operations are completed. However, the
|
|
service provider guarantees to the client that posted buffers are sent
|
|
in the same order they are supplied.
|
|
|
|
Arguments:
|
|
|
|
s - A descriptor identifying a connected socket.
|
|
|
|
lpBuffers - A pointer to an array of WSABUF structures. Each WSABUF
|
|
structure contains a pointer to a buffer and the length of the
|
|
buffer. This array must remain valid for the duration of the
|
|
send operation.
|
|
|
|
dwBufferCount - The number of WSABUF structures in the lpBuffers array.
|
|
|
|
lpNumberOfBytesSent - A pointer to the number of bytes sent by this
|
|
call.
|
|
|
|
dwFlags - Specifies the way in which the call is made.
|
|
|
|
lpOverlapped - A pointer to a WSAOVERLAPPED structure.
|
|
|
|
lpCompletionRoutine - A pointer to the completion routine called when
|
|
the send operation has been completed.
|
|
|
|
lpThreadId - A pointer to a thread ID structure to be used by the
|
|
provider in a subsequent call to WPUQueueApc(). The provider should
|
|
store the referenced WSATHREADID structure (not the pointer to same)
|
|
until after the WPUQueueApc() function returns.
|
|
|
|
lpErrno - A pointer to the error code.
|
|
|
|
Return Value:
|
|
|
|
If no error occurs and the send operation has completed immediately,
|
|
WSPSend() returns 0. Note that in this case the completion routine, if
|
|
specified, will have already been queued. Otherwise, a value of
|
|
SOCKET_ERROR is returned, and a specific error code is available in
|
|
lpErrno. The error code WSA_IO_PENDING indicates that the overlapped
|
|
operation has been successfully initiated and that completion will be
|
|
indicated at a later time. Any other error code indicates that no
|
|
overlapped operation was initiated and no completion indication will
|
|
occur.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
} // WSPSend
|
|
|
|
|
|
INT
|
|
WSPAPI
|
|
WSPSendDisconnect(
|
|
IN SOCKET s,
|
|
IN LPWSABUF lpOutboundDisconnectData,
|
|
OUT LPINT lpErrno
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is used on connection-oriented sockets to disable
|
|
transmission, and to initiate termination of the connection along with the
|
|
transmission of disconnect data, if any.
|
|
|
|
After this routine has been successfully issued, subsequent sends are
|
|
disallowed.
|
|
|
|
lpOutboundDisconnectData, if not NULL, points to a buffer containing the
|
|
outgoing disconnect data to be sent to the remote party.
|
|
|
|
Note that WSPSendDisconnect() does not close the socket, and resources
|
|
attached to the socket will not be freed until WSPCloseSocket() is invoked.
|
|
|
|
WSPSendDisconnect() does not block regardless of the SO_LINGER setting on
|
|
the socket.
|
|
|
|
A WinSock SPI client should not rely on being able to re-use a socket after
|
|
it has been WSPSendDisconnect()ed. In particular, a WinSock provider is not
|
|
required to support the use of WSPConnect() on such a socket.
|
|
|
|
Arguments:
|
|
|
|
s - A descriptor identifying a socket.
|
|
|
|
lpOutboundDisconnectData - A pointer to the outgoing disconnect data.
|
|
|
|
lpErrno - A pointer to the error code.
|
|
|
|
Return Value:
|
|
|
|
If no error occurs, WSPSendDisconnect() returns 0. Otherwise, a value of
|
|
SOCKET_ERROR is returned, and a specific error code is available in
|
|
lpErrno.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
} // WSPSendDisconnect
|
|
|
|
|
|
INT
|
|
WSPAPI
|
|
WSPSendTo(
|
|
IN SOCKET s,
|
|
IN LPWSABUF lpBuffers,
|
|
IN DWORD dwBufferCount,
|
|
OUT LPDWORD lpNumberOfBytesSent,
|
|
IN DWORD dwFlags,
|
|
IN const struct sockaddr FAR * lpTo,
|
|
IN int iTolen,
|
|
IN LPWSAOVERLAPPED lpOverlapped,
|
|
IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
|
|
IN LPWSATHREADID lpThreadId,
|
|
OUT LPINT lpErrno
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is normally used on a connectionless socket specified by s
|
|
to send a datagram contained in one or more buffers to a specific peer
|
|
socket identified by the lpTo parameter. On a connection-oriented socket,
|
|
the lpTo and iToLen parameters are ignored; in this case the WSPSendTo()
|
|
is equivalent to WSPSend().
|
|
|
|
For overlapped sockets (created using WSPSocket() with flag
|
|
WSA_FLAG_OVERLAPPED) this will occur using overlapped I/O, unless both
|
|
lpOverlapped and lpCompletionRoutine are NULL in which case the socket is
|
|
treated as a non-overlapped socket. A completion indication will occur
|
|
(invocation of the completion routine or setting of an event object) when
|
|
the supplied buffer(s) have been consumed by the transport. If the
|
|
operation does not complete immediately, the final completion status is
|
|
retrieved via the completion routine or WSPGetOverlappedResult().
|
|
|
|
For non-overlapped sockets, the parameters lpOverlapped,
|
|
lpCompletionRoutine, and lpThreadId are ignored and WSPSend() adopts the
|
|
regular synchronous semantics. Data is copied from the supplied buffer(s)
|
|
into the transport's buffer. If the socket is non-blocking and stream-
|
|
oriented, and there is not sufficient space in the transport's buffer,
|
|
WSPSend() will return with only part of the supplied buffers having been
|
|
consumed. Given the same buffer situation and a blocking socket, WSPSend()
|
|
will block until all of the supplied buffer contents have been consumed.
|
|
|
|
The array of WSABUF structures pointed to by the lpBuffers parameter is
|
|
transient. If this operation completes in an overlapped manner, it is the
|
|
service provider's responsibility to capture these WSABUF structures
|
|
before returning from this call. This enables applications to build stack-
|
|
based WSABUF arrays.
|
|
|
|
For message-oriented sockets, care must be taken not to exceed the maximum
|
|
message size of the underlying provider, which can be obtained by getting
|
|
the value of socket option SO_MAX_MSG_SIZE. If the data is too long to
|
|
pass atomically through the underlying protocol the error WSAEMSGSIZE is
|
|
returned, and no data is transmitted.
|
|
|
|
Note that the successful completion of a WSPSendTo() does not indicate that
|
|
the data was successfully delivered.
|
|
|
|
dwFlags may be used to influence the behavior of the function invocation
|
|
beyond the options specified for the associated socket. That is, the
|
|
semantics of this routine are determined by the socket options and the
|
|
dwFlags parameter. The latter is constructed by or-ing any of the
|
|
following values:
|
|
|
|
MSG_DONTROUTE - Specifies that the data should not be subject
|
|
to routing. A WinSock service provider may choose to ignore this
|
|
flag.
|
|
|
|
MSG_OOB - Send out-of-band data (stream style socket such as
|
|
SOCK_STREAM only).
|
|
|
|
MSG_PARTIAL - Specifies that lpBuffers only contains a partial
|
|
message. Note that the error code WSAEOPNOTSUPP will be returned
|
|
which do not support partial message transmissions.
|
|
|
|
If an overlapped operation completes immediately, WSPSendTo() returns a
|
|
value of zero and the lpNumberOfBytesSent parameter is updated with the
|
|
number of bytes sent. If the overlapped operation is successfully
|
|
initiated and will complete later, WSPSendTo() returns SOCKET_ERROR and
|
|
indicates error code WSA_IO_PENDING. In this case, lpNumberOfBytesSent is
|
|
not updated. When the overlapped operation completes the amount of data
|
|
transferred is indicated either via the cbTransferred parameter in the
|
|
completion routine (if specified), or via the lpcbTransfer parameter in
|
|
WSPGetOverlappedResult().
|
|
|
|
Providers must allow this routine to be called from within the completion
|
|
routine of a previous WSPRecv(), WSPRecvFrom(), WSPSend() or WSPSendTo()
|
|
function. However, for a given socket, I/O completion routines may not be
|
|
nested. This permits time-sensitive data transmissions to occur entirely
|
|
within a preemptive context.
|
|
|
|
The lpOverlapped parameter must be valid for the duration of the
|
|
overlapped operation. If multiple I/O operations are simultaneously
|
|
outstanding, each must reference a separate overlapped structure. The
|
|
WSAOVERLAPPED structure has the following form:
|
|
|
|
typedef struct _WSAOVERLAPPED {
|
|
DWORD Internal; // reserved
|
|
DWORD InternalHigh; // reserved
|
|
DWORD Offset; // reserved
|
|
DWORD OffsetHigh; // reserved
|
|
WSAEVENT hEvent;
|
|
} WSAOVERLAPPED, FAR * LPWSAOVERLAPPED;
|
|
|
|
If the lpCompletionRoutine parameter is NULL, the service provider signals
|
|
the hEvent field of lpOverlapped when the overlapped operation completes
|
|
if it contains a valid event object handle. The WinSock SPI client can use
|
|
WSPGetOverlappedResult() to wait or poll on the event object.
|
|
|
|
If lpCompletionRoutine is not NULL, the hEvent field is ignored and can be
|
|
used by the WinSock SPI client to pass context information to the
|
|
completion routine. It is the service provider's responsibility to arrange
|
|
for invocation of the client-specified completion routine when the
|
|
overlapped operation completes. Since the completion routine must be
|
|
executed in the context of the same thread that initiated the overlapped
|
|
operation, it cannot be invoked directly from the service provider. The
|
|
WinSock DLL offers an asynchronous procedure call (APC) mechanism to
|
|
facilitate invocation of completion routines.
|
|
|
|
A service provider arranges for a function to be executed in the proper
|
|
thread by calling WPUQueueApc(). Note that this routine must be invoked
|
|
while in the context of the same process (but not necessarily the same
|
|
thread) that was used to initiate the overlapped operation. It is the
|
|
service provider's responsibility to arrange for this process context to
|
|
be active prior to calling WPUQueueApc().
|
|
|
|
WPUQueueApc() takes as input parameters a pointer to a WSATHREADID
|
|
structure (supplied to the provider via the lpThreadId input parameter),
|
|
a pointer to an APC function to be invoked, and a 32 bit context value
|
|
that is subsequently passed to the APC function. Because only a single
|
|
32-bit context value is available, the APC function cannot itself be the
|
|
client-specified completion routine. The service provider must instead
|
|
supply a pointer to its own APC function which uses the supplied context
|
|
value to access the needed result information for the overlapped operation,
|
|
and then invokes the client-specified completion routine.
|
|
|
|
The prototype for the client-supplied completion routine is as follows:
|
|
|
|
void
|
|
CALLBACK
|
|
CompletionRoutine(
|
|
IN DWORD dwError,
|
|
IN DWORD cbTransferred,
|
|
IN LPWSAOVERLAPPED lpOverlapped,
|
|
IN DWORD dwFlags
|
|
);
|
|
|
|
CompletionRoutine is a placeholder for a client supplied function
|
|
name.
|
|
|
|
dwError specifies the completion status for the overlapped
|
|
operation as indicated by lpOverlapped.
|
|
|
|
cbTransferred specifies the number of bytes sent.
|
|
|
|
No flag values are currently defined and the dwFlags value will
|
|
be zero.
|
|
|
|
This routine does not return a value.
|
|
|
|
The completion routines may be called in any order, not necessarily in
|
|
the same order the overlapped operations are completed. However, the
|
|
service provider guarantees to the client that posted buffers are sent
|
|
in the same order they are supplied.
|
|
|
|
Arguments:
|
|
|
|
s - A descriptor identifying a socket.
|
|
|
|
lpBuffers - A pointer to an array of WSABUF structures. Each WSABUF
|
|
structure contains a pointer to a buffer and the length of the
|
|
buffer. This array must remain valid for the duration of the
|
|
send operation.
|
|
|
|
dwBufferCount - The number of WSABUF structures in the lpBuffers
|
|
array.
|
|
|
|
lpNumberOfBytesSent - A pointer to the number of bytes sent by this
|
|
call.
|
|
|
|
dwFlags - Specifies the way in which the call is made.
|
|
|
|
lpTo - An optional pointer to the address of the target socket.
|
|
|
|
iTolen - The size of the address in lpTo.
|
|
|
|
lpOverlapped - A pointer to a WSAOVERLAPPED structure.
|
|
|
|
lpCompletionRoutine - A pointer to the completion routine called
|
|
when the send operation has been completed.
|
|
|
|
lpThreadId - A pointer to a thread ID structure to be used by the
|
|
provider in a subsequent call to WPUQueueApc(). The provider
|
|
should store the referenced WSATHREADID structure (not the
|
|
pointer to same) until after the WPUQueueApc() function returns.
|
|
|
|
lpErrno - A pointer to the error code.
|
|
|
|
Return Value:
|
|
|
|
If no error occurs and the send operation has completed immediately,
|
|
WSPSendTo() returns 0. Note that in this case the completion routine, if
|
|
specified, will have already been queued. Otherwise, a value of
|
|
SOCKET_ERROR is returned, and a specific error code is available in
|
|
lpErrno. The error code WSA_IO_PENDING indicates that the overlapped
|
|
operation has been successfully initiated and that completion will be
|
|
indicated at a later time. Any other error code indicates that no
|
|
overlapped operation was initiated and no completion indication will occur.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
} // WSPSendTo
|
|
|
|
|
|
INT
|
|
WSPAPI
|
|
WSPSetSockOpt(
|
|
IN SOCKET s,
|
|
IN int level,
|
|
IN int optname,
|
|
IN const char FAR * optval,
|
|
IN int optlen,
|
|
OUT LPINT lpErrno
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine sets the current value for a socket option associated with a
|
|
socket of any type, in any state. Although options may exist at multiple
|
|
protocol levels, they are always present at the uppermost "socket' level.
|
|
Options affect socket operations, such as whether broadcast messages may
|
|
be sent on the socket, etc.
|
|
|
|
There are two types of socket options: Boolean options that enable or
|
|
disable a feature or behavior, and options which require an integer value
|
|
or structure. To enable a Boolean option, optval points to a nonzero
|
|
integer. To disable the option optval points to an integer equal to zero.
|
|
optlen should be equal to sizeof(int) for Boolean options. For other
|
|
options, optval points to the an integer or structure that contains the
|
|
desired value for the option, and optlen is the length of the integer or
|
|
structure.
|
|
|
|
Value Type Meaning
|
|
~~~~~ ~~~~ ~~~~~~~
|
|
SO_BROADCAST BOOL Allow transmission of broadcast
|
|
messages on the socket.
|
|
SO_DEBUG BOOL Record debugging information.
|
|
SO_DONTLINGER BOOL Don't block close waiting for
|
|
unsent data to be sent. Setting
|
|
this option is equivalent to
|
|
setting SO_LINGER with l_onoff set
|
|
to zero.
|
|
SO_DONTROUTE BOOL Don't route: send directly to
|
|
interface.
|
|
SO_GROUP_PRIORITY int Specify the relative priority to
|
|
be established for sockets that
|
|
are part of a socket group.
|
|
SO_KEEPALIVE BOOL Send keepalives.
|
|
SO_LINGER struct linger Linger on close if unsent data is
|
|
present.
|
|
SO_OOBINLINE BOOL Receive out-of-band data in the
|
|
normal data stream.
|
|
SO_RCVBUF int Specify buffer size for receives.
|
|
SO_REUSEADDR BOOL Allow the socket to be bound to an
|
|
address which is already in use.
|
|
(See WSPBind().)
|
|
SO_SNDBUF int Specify buffer size for sends.
|
|
PVD_CONFIG Service This object stores the
|
|
Provider configuration information for the
|
|
Dependent service provider associated with
|
|
socket s. The exact format of this
|
|
data structure is service provider
|
|
specific.
|
|
|
|
Calling WSPSetSockOpt() with an unsupported option will result in an error
|
|
code of WSAENOPROTOOPT being returned in lpErrno.
|
|
|
|
SO_DEBUG - WinSock service providers are encouraged (but not required) to
|
|
supply output debug information if the SO_DEBUG option is set by a WinSock
|
|
SPI client. The mechanism for generating the debug information and the form
|
|
it takes are beyond the scope of this specification.
|
|
|
|
SO_GROUP_PRIORITY - Group priority indicates the priority of the specified
|
|
socket relative to other sockets within the socket group. Values are non-
|
|
negative integers, with zero corresponding to the highest priority.
|
|
Priority values represent a hint to the service provider about how
|
|
potentially scarce resources should be allocated. For example, whenever
|
|
two or more sockets are both ready to transmit data, the highest priority
|
|
socket (lowest value for SO_GROUP_PRIORITY) should be serviced first, with
|
|
the remainder serviced in turn according to their relative priorities.
|
|
|
|
The WSAENOPROTOOPT error is indicated for non group sockets or for service
|
|
providers which do not support group sockets.
|
|
|
|
SO_KEEPALIVE - An WinSock SPI client may request that a TCP/IP provider
|
|
enable the use of "keep-alive" packets on TCP connections by turning on the
|
|
SO_KEEPALIVE socket option. A WinSock provider need not support the use of
|
|
keep-alives: if it does, the precise semantics are implementation-specific
|
|
but should conform to section 4.2.3.6 of RFC 1122: Requirements for
|
|
Internet Hosts -- Communication Layers. If a connection is dropped as the
|
|
result of "keep-alives" the error code WSAENETRESET is returned to any
|
|
calls in progress on the socket, and any subsequent calls will fail with
|
|
WSAENOTCONN.
|
|
|
|
SO_LINGER - SO_LINGER controls the action taken when unsent data is queued
|
|
on a socket and a WSPCloseSocket() is performed. See WSPCloseSocket() for a
|
|
description of the way in which the SO_LINGER settings affect the semantics
|
|
of WSPCloseSocket(). The WinSock SPI client sets the desired behavior by
|
|
creating a struct linger (pointed to by the optval argument) with the
|
|
following elements:
|
|
|
|
struct linger {
|
|
u_short l_onoff;
|
|
u_short l_linger;
|
|
};
|
|
|
|
To enable SO_LINGER, a WinSock SPI client should set l_onoff to a non-zero
|
|
value, set l_linger to 0 or the desired timeout (in seconds), and call
|
|
WSPSetSockOpt(). To enable SO_DONTLINGER (i.e. disable SO_LINGER) l_onoff
|
|
should be set to zero and WSPSetSockOpt() should be called. Note that
|
|
enabling SO_LINGER with a non-zero timeout on a non-blocking socket is not
|
|
recommended (see WSPCloseSocket() for details).
|
|
|
|
Enabling SO_LINGER also disables SO_DONTLINGER, and vice versa. Note that
|
|
if SO_DONTLINGER is DISABLED (i.e. SO_LINGER is ENABLED) then no timeout
|
|
value is specified. In this case the timeout used is implementation
|
|
dependent. If a previous timeout has been established for a socket (by
|
|
enabling SO_LINGER), then this timeout value should be reinstated by the
|
|
service provider.
|
|
|
|
SO_REUSEADDR - By default, a socket may not be bound (see WSPBind()) to a
|
|
local address which is already in use. On occasions, however, it may be
|
|
desirable to "re-use" an address in this way. Since every connection is
|
|
uniquely identified by the combination of local and remote addresses, there
|
|
is no problem with having two sockets bound to the same local address as
|
|
long as the remote addresses are different. To inform the WinSock provider
|
|
that a WSPBind() on a socket should be allowed to bind to a local address
|
|
that is already in use by another socket, the WinSock SPI client should set
|
|
the SO_REUSEADDR socket option for the socket before issuing the WSPBind().
|
|
Note that the option is interpreted only at the time of the WSPBind(): it
|
|
is therefore unnecessary (but harmless) to set the option on a socket which
|
|
is not to be bound to an existing address, and setting or resetting the
|
|
option after the WSPBind() has no effect on this or any other socket.
|
|
|
|
SO_RCVBUF & SO_SNDBUF - When a Windows Sockets implementation supports the
|
|
SO_RCVBUF and SO_SNDBUF options, a WinSock SPI client may request different
|
|
buffer sizes (larger or smaller). The call may succeed even though the
|
|
service provider did not make available the entire amount requested. A
|
|
WinSock SPI client must call WSPGetSockOpt() with the same option to check
|
|
the buffer size actually provided.
|
|
|
|
PVD_CONFIG - This object stores the configuration information for the
|
|
service provider associated with socket s. The exact format of this data
|
|
structure is service provider specific.
|
|
|
|
Arguments:
|
|
|
|
s - A descriptor identifying a socket.
|
|
|
|
level - The level at which the option is defined; the supported levels
|
|
include SOL_SOCKET.
|
|
|
|
optname - The socket option for which the value is to be set.
|
|
|
|
optval - A pointer to the buffer in which the value for the requested
|
|
option is supplied.
|
|
|
|
optlen - The size of the optval buffer.
|
|
|
|
lpErrno - A pointer to the error code.
|
|
|
|
Return Value:
|
|
|
|
If no error occurs, WSPSetSockOpt() returns 0. Otherwise, a value of
|
|
SOCKET_ERROR is returned, and a specific error code is available in
|
|
lpErrno.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
} // WSPSetSockOpt
|
|
|
|
|
|
INT
|
|
WSPAPI
|
|
WSPShutdown(
|
|
IN SOCKET s,
|
|
IN int how,
|
|
OUT LPINT lpErrno
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is used on all types of sockets to disable reception,
|
|
transmission, or both.
|
|
|
|
If how is SD_RECEIVE, subsequent receives on the socket will be
|
|
disallowed. This has no effect on the lower protocol layers. For TCP
|
|
sockets, if there is still data queued on the socket waiting to be
|
|
received, or data arrives subsequently, the connection is reset, since the
|
|
data cannot be delivered to the user. For UDP sockets, incoming datagrams
|
|
are accepted and queued. In no case will an ICMP error packet
|
|
be generated.
|
|
|
|
If how is SD_SEND, subsequent sends on the socket are disallowed. For TCP
|
|
sockets, a FIN will be sent. Setting how to SD_BOTH disables both sends
|
|
and receives as described above.
|
|
|
|
Note that WSPShutdown() does not close the socket, and resources attached
|
|
to the socket will not be freed until WSPCloseSocket() is invoked.
|
|
|
|
WSPShutdown() does not block regardless of the SO_LINGER setting on the
|
|
socket. A WinSock SPI client should not rely on being able to re-use a
|
|
socket after it has been shut down. In particular, a WinSock service
|
|
provider is not required to support the use of WSPConnect() on such a
|
|
socket.
|
|
|
|
Arguments:
|
|
|
|
s - A descriptor identifying a socket.
|
|
|
|
how - A flag that describes what types of operation will no longer be
|
|
allowed.
|
|
|
|
lpErrno - A pointer to the error code.
|
|
|
|
Return Value:
|
|
|
|
If no error occurs, WSPShutdown() returns 0. Otherwise, a value of
|
|
SOCKET_ERROR is returned, and a specific error code is available
|
|
in lpErrno.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
} // WSPShutdown
|
|
|
|
|
|
SOCKET
|
|
WSPAPI
|
|
WSPSocket(
|
|
IN int af,
|
|
IN int type,
|
|
IN int protocol,
|
|
IN LPWSAPROTOCOL_INFOW lpProtocolInfo,
|
|
IN GROUP g,
|
|
IN DWORD dwFlags,
|
|
OUT LPINT lpErrno
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
WSPSocket() causes a socket descriptor and any related resources to be
|
|
allocated. By default, the created socket will not have the overlapped
|
|
attribute. WinSock providers are encouraged to be realized as Windows
|
|
installable file systems, and supply system file handles as socket
|
|
descriptors. These providers must call WPUModifyIFSHandle() prior to
|
|
returning from this routine For non-file-system WinSock providers,
|
|
WPUCreateSocketHandle() must be used to acquire a unique socket descriptor
|
|
from the WinSock 2 DLL prior to returning from this routine.
|
|
|
|
The values for af, type and protocol are those supplied by the application
|
|
in the corresponding API functions socket() or WSASocket(). A service
|
|
provider is free to ignore or pay attention to any or all of these values
|
|
as is appropriate for the particular protocol. However, the provider must
|
|
be willing to accept the value of zero for af and type, since the
|
|
WinSock 2 DLL considers these to be wild card values. Also the value of
|
|
manifest constant FROM_PROTOCOL_INFOW must be accepted for any of af, type
|
|
and protocol. This value indicates that the WinSock 2 application wishes to
|
|
use the corresponding values from the indicated WSAPROTOCOL_INFOW struct:
|
|
|
|
iAddressFamily
|
|
iSocketType
|
|
iProtocol
|
|
|
|
Parameter g is used to indicate the appropriate actions on socket groups:
|
|
|
|
If g is an existing socket group ID, join the new socket to this
|
|
group, provided all the requirements set by this group are met.
|
|
|
|
If g = SG_UNCONSTRAINED_GROUP, create an unconstrained socket
|
|
group and have the new socket be the first member.
|
|
|
|
If g = SG_CONSTRAINED_GROUP, create a constrained socket group and
|
|
have the new socket be the first member.
|
|
|
|
If g = zero, no group operation is performed.
|
|
|
|
Any set of sockets grouped together must be implemented by a single
|
|
service provider. For unconstrained groups, any set of sockets may be
|
|
grouped together. A constrained socket group may consist only of
|
|
connection-oriented sockets, and requires that connections on all grouped
|
|
sockets be to the same address on the same host. For newly created socket
|
|
groups, the new group ID must be available for the WinSock SPI client to
|
|
retrieve by calling WSPGetSockOpt() with option SO_GROUP_ID. A socket group
|
|
and its associated ID remain valid until the last socket belonging to this
|
|
socket group is closed. Socket group IDs are unique across all processes
|
|
for a given service provider.
|
|
|
|
The dwFlags parameter may be used to specify the attributes of the socket
|
|
by OR-ing any of the following Flags:
|
|
|
|
WSA_FLAG_OVERLAPPED - This flag causes an overlapped socket to
|
|
be created. Overlapped sockets may utilize WSPSend(),
|
|
WSPSendTo(), WSPRecv(), WSPRecvFrom() and WSPIoctl() for
|
|
overlapped I/O operations, which allows multiple operations
|
|
to be initiated and in progress simultaneously.
|
|
|
|
WSA_FLAG_MULTIPOINT_C_ROOT - Indicates that the socket created
|
|
will be a c_root in a multipoint session. Only allowed if a
|
|
rooted control plane is indicated in the protocol's
|
|
WSAPROTOCOL_INFOW struct.
|
|
|
|
WSA_FLAG_MULTIPOINT_C_LEAF - Indicates that the socket created
|
|
will be a c_leaf in a multicast session. Only allowed if
|
|
XP1_SUPPORT_MULTIPOINT is indicated in the protocol's
|
|
WSAPROTOCOL_INFOW struct.
|
|
|
|
WSA_FLAG_MULTIPOINT_D_ROOT - Indicates that the socket created
|
|
will be a d_root in a multipoint session. Only allowed if a
|
|
rooted data plane is indicated in the protocol's
|
|
WSAPROTOCOL_INFOW struct.
|
|
|
|
WSA_FLAG_MULTIPOINT_D_LEAF - Indicates that the socket created
|
|
will be a d_leaf in a multipoint session. Only allowed if
|
|
XP1_SUPPORT_MULTIPOINT is indicated in the protocol's
|
|
WSAPROTOCOL_INFOW struct.
|
|
|
|
N.B For multipoint sockets, exactly one of WSA_FLAG_MULTIPOINT_C_ROOT
|
|
or WSA_FLAG_MULTIPOINT_C_LEAF must be specified, and exactly one of
|
|
WSA_FLAG_MULTIPOINT_D_ROOT or WSA_FLAG_MULTIPOINT_D_LEAF must be
|
|
specified.
|
|
|
|
Connection-oriented sockets such as SOCK_STREAM provide full-duplex
|
|
connections, and must be in a connected state before any data may be sent
|
|
or received on them. A connection to another socket is created with a
|
|
WSPConnect() call. Once connected, data may be transferred using WSPSend()
|
|
and WSPRecv() calls. When a session has been completed, a WSPCloseSocket()
|
|
must be performed.
|
|
|
|
The communications protocols used to implement a reliable, connection-
|
|
oriented socket ensure that data is not lost or duplicated. If data for
|
|
which the peer protocol has buffer space cannot be successfully
|
|
transmitted within a reasonable length of time, the connection is
|
|
considered broken and subsequent calls will fail with the error code set
|
|
to WSAETIMEDOUT.
|
|
|
|
Connectionless, message-oriented sockets allow sending and receiving of
|
|
datagrams to and from arbitrary peers using WSPSendTo() and WSPRecvFrom().
|
|
If such a socket is WSPConnect()ed to a specific peer, datagrams may be
|
|
sent to that peer using WSPSend() and may be received from (only) this
|
|
peer using WSPRecv().
|
|
|
|
Support for sockets with type SOCK_RAW is not required but service
|
|
providers are encouraged to support raw sockets whenever it makes sense
|
|
to do so.
|
|
|
|
When a special WSAPROTOCOL_INFOW struct (obtained via the
|
|
WSPDuplicateSocket() function and used to create additional descriptors
|
|
for a shared socket) is passed as an input parameter to WSPSocket(),
|
|
the g and dwFlags parameters are ignored.
|
|
|
|
Arguments:
|
|
|
|
af- An address family specification.
|
|
|
|
type - A type specification for the new socket.
|
|
|
|
protocol - A particular protocol to be used with the socket which is
|
|
specific to the indicated address family.
|
|
|
|
lpProtocolInfo - A pointer to a WSAPROTOCOL_INFOW struct that defines
|
|
the characteristics of the socket to be created.
|
|
|
|
g - The identifier of the socket group which the new socket is to join.
|
|
|
|
dwFlags - The socket attribute specification.
|
|
|
|
lpErrno - A pointer to the error code.
|
|
|
|
Return Value:
|
|
|
|
If no error occurs, WSPSocket() returns a descriptor referencing the
|
|
new socket. Otherwise, a value of INVALID_SOCKET is returned, and a
|
|
specific error code is available in lpErrno.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
} // WSPSocket
|
|
|
|
|
|
INT
|
|
WSPAPI
|
|
WSPStartup(
|
|
IN WORD wVersionRequested,
|
|
OUT LPWSPDATA lpWSPData,
|
|
IN LPWSAPROTOCOL_INFOW lpProtocolInfo,
|
|
IN WSPUPCALLTABLE UpcallTable,
|
|
OUT LPWSPPROC_TABLE lpProcTable
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine MUST be the first WinSock SPI function called by a WinSock
|
|
SPI client on a per-process basis. It allows the client to specify the
|
|
version of WinSock SPI required and to provide its upcall dispatch table.
|
|
All upcalls, i.e., functions prefixed with WPU, made by the WinSock
|
|
service provider are invoked via the client's upcall dispatch table.
|
|
This routine also allows the client to retrieve details of the specific
|
|
WinSock service provider implementation. The WinSock SPI client may only
|
|
issue further WinSock SPI functions after a successful WSPStartup()
|
|
invocation. A table of pointers to the rest of the SPI functions is
|
|
retrieved via the lpProcTable parameter.
|
|
|
|
In order to support future versions of the WinSock SPI and the WinSock 2
|
|
DLL which may have functionality differences from the current WinSock SPI,
|
|
a negotiation takes place in WSPStartup(). The caller of WSPStartup()
|
|
(either the WinSock 2 DLL or a layered protocol) and the WinSock service
|
|
provider 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 WSPStartup(), the WinSock service provider examines the version
|
|
requested by the client. If this version is equal to or higher than the
|
|
lowest version supported by the service provider, the call succeeds and
|
|
the service provider returns in wHighVersion the highest version it
|
|
supports and in wVersion the minimum of its high version and
|
|
wVersionRequested. The WinSock service provider then assumes that the
|
|
WinSock SPI client will use wVersion. If the wVersion field of the WSPDATA
|
|
structure is unacceptable to the caller, it should call WSPCleanup() and
|
|
either search for another WinSock service provider or fail to initialize.
|
|
|
|
This negotiation allows both a WinSock service provider and a WinSock SPI
|
|
client to support a range of WinSock versions. A client can successfully
|
|
utilize a WinSock service provider if there is any overlap in the version
|
|
ranges. The following chart gives examples of how WSPStartup() works in
|
|
conjunction with different WinSock DLL and WinSock service provider (SP)
|
|
versions:
|
|
|
|
DLL SP wVersion- wVersion wHigh- End
|
|
Version Version Requested Version 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 fragment demonstrates how a WinSock SPI client which
|
|
supports only version 2.0 of WinSock SPI makes a WSPStartup() call:
|
|
|
|
WORD wVersionRequested;
|
|
WSPDATA WSPData;
|
|
|
|
int err;
|
|
|
|
WSPUPCALLTABLE upcallTable =
|
|
{
|
|
// initialize upcallTable with function pointers
|
|
};
|
|
|
|
LPWSPPROC_TABLE lpProcTable =
|
|
{
|
|
// allocate memory for the ProcTable
|
|
};
|
|
|
|
wVersionRequested = MAKEWORD( 2, 0 );
|
|
|
|
err = WSPStartup( wVersionRequested, &WSPData,
|
|
lpProtocolBuffer, upcallTable, lpProcTable );
|
|
if ( err != 0 ) {
|
|
// Tell the user that we couldn't find a useable
|
|
// WinSock service provider.
|
|
return;
|
|
}
|
|
|
|
// Confirm that the WinSock service provider supports 2.0.
|
|
// Note that if the service provider supports versions
|
|
// greater than 2.0 in addition to 2.0, it will still
|
|
// return 2.0 in wVersion since that is the version we
|
|
// requested.
|
|
|
|
if ( LOBYTE( WSPData.wVersion ) != 2 ||
|
|
HIBYTE( WSPData.wVersion ) != 0 ) {
|
|
// Tell the user that we couldn't find a useable
|
|
// WinSock service provider.
|
|
WSPCleanup( );
|
|
return;
|
|
}
|
|
|
|
// The WinSock service provider is acceptable. Proceed.
|
|
|
|
And this code fragment demonstrates how a WinSock service provider which
|
|
supports only version 2.0 performs the WSPStartup() negotiation:
|
|
|
|
// Make sure that the version requested is >= 2.0.
|
|
// The low byte is the major version and the high
|
|
// byte is the minor version.
|
|
|
|
if ( LOBYTE( wVersionRequested ) < 2) {
|
|
return WSAVERNOTSUPPORTED;
|
|
}
|
|
|
|
// Since we only support 2.0, set both wVersion and
|
|
// wHighVersion to 2.0.
|
|
|
|
lpWSPData->wVersion = MAKEWORD( 2, 0 );
|
|
lpWSPData->wHighVersion = MAKEWORD( 2, 0 );
|
|
|
|
Once the WinSock SPI client has made a successful WSPStartup() call, it
|
|
may proceed to make other WinSock SPI calls as needed. When it has
|
|
finished using the services of the WinSock service provider, the client
|
|
must call WSPCleanup() in order to allow the WinSock service provider to
|
|
free any resources allocated for the client.
|
|
|
|
Details of how WinSock service provider information is encoded in the
|
|
WSPData structure is as follows:
|
|
|
|
typedef struct WSPData {
|
|
WORD wVersion;
|
|
WORD wHighVersion;
|
|
char szDescription[WSPDESCRIPTION_LEN+1];
|
|
} WSPDATA, FAR * LPWSPDATA;
|
|
|
|
The members of this structure are:
|
|
|
|
wVersion- The version of the WinSock SPI specification that the
|
|
WinSock service provider expects the caller to use.
|
|
|
|
wHighVersion - The highest version of the WinSock SPI specification
|
|
that this service provider can support (also encoded as above).
|
|
Normally this will be the same as wVersion.
|
|
|
|
szDescription - A null-terminated ASCII string into which the
|
|
WinSock provider copies a description of itself. The text
|
|
(up to 256 characters in length) may contain any characters
|
|
except control and formatting characters: the most likely use
|
|
that a SPI client will put this to is to display it (possibly
|
|
truncated) in a status message.
|
|
|
|
A WinSock SPI client may call WSPStartup() more than once if it needs to
|
|
obtain the WSPData structure information more than once. On each such
|
|
call the client may specify any version number supported by the provider.
|
|
|
|
There must be one WSPCleanup() call corresponding to every successful
|
|
WSPStartup() call to allow third-party DLLs to make use of a WinSock
|
|
provider. This means, for example, that if WSPStartup() is called three
|
|
times, the corresponding call to WSPCleanup() must occur three times.
|
|
The first two calls to WSPCleanup() do nothing except decrement an
|
|
internal counter; the final WSPCleanup() call does all necessary resource
|
|
deallocation.
|
|
|
|
Arguments:
|
|
|
|
wVersionRequested - The highest version of WinSock 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 - A pointer to the WSPDATA data structure that is to receive
|
|
details of the WinSock service provider.
|
|
|
|
lpProtocolInfo - A pointer to a WSAPROTOCOL_INFOW struct 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 - The WinSock 2 DLL's upcall dispatch table.
|
|
|
|
lpProcTable - A pointer to the table of SPI function pointers.
|
|
|
|
Return Value:
|
|
|
|
WSPStartup() returns zero if successful. Otherwise it returns an error
|
|
code.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
} // WSPStartup
|
|
|
|
|
|
INT
|
|
WSPAPI
|
|
WSPStringToAddress(
|
|
IN LPWSTR AddressString,
|
|
IN INT AddressFamily,
|
|
IN LPWSAPROTOCOL_INFOW lpProtocolInfo,
|
|
OUT LPSOCKADDR lpAddress,
|
|
IN OUT LPINT lpAddressLength,
|
|
OUT LPINT lpErrno
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine converts a human-readable string to a socket address
|
|
structure (SOCKADDR) suitable for pass to Windows Sockets routines which
|
|
take such a structure. Any missing components of the address will be
|
|
defaulted to a reasonable value if possible. For example, a missing port
|
|
number will be defaulted to zero.
|
|
|
|
Arguments:
|
|
|
|
AddressString - Points to the zero-terminated human-readable string to
|
|
convert.
|
|
|
|
AddressFamily - The address family to which the string belongs, or
|
|
AF_UNSPEC if it is unknown.
|
|
|
|
lpProtocolInfo - The provider's WSAPROTOCOL_INFOW struct.
|
|
|
|
lpAddress - A buffer which is filled with a single SOCKADDR structure.
|
|
|
|
lpAddressLength - The length of the Address buffer. Returns the size of
|
|
the resultant SOCKADDR structure.
|
|
|
|
lpErrno - A pointer to the error code.
|
|
|
|
Return Value:
|
|
|
|
If no error occurs, WSPStringToAddress() returns 0. Otherwise, a value
|
|
of SOCKET_ERROR is returned, and a specific error code is available
|
|
in lpErrno.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
} // WSPStringToAddress
|
|
|