Platform SDK: Windows Sockets

WSPIoctl

The WSPIoctl function controls the mode of a socket.

int WSPIoctl (
  SOCKET            s,                                                
  DWORD             dwIoControlCode,                                   
  LPVOID            lpvInBuffer,                                      
  DWORD             cbInBuffer,                                        
  LPVOID            lpvOutBuffer,                                     
  DWORD             cbOutBuffer,                                       
  LPDWORD           lpcbBytesReturned,                               
  LPWSAOVERLAPPED   lpOverlapped,                            
  LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,  
  LPWSATHREADID     lpThreadId,                                
  LPINT             lpErrno                                            
);

Parameters

s
[in] Handle to a socket.
dwIoControlCode
[in] Control code of the operation to perform.
lpvInBuffer
[in] Address of input buffer.
cbInBuffer
[in] Size of input buffer.
lpvOutBuffer
[out] Address of output buffer.
cbOutBuffer
[in] Size of output buffer.
lpcbBytesReturned
[out] Pointer to the size of output buffer's contents.
lpOverlapped
[in] Address of WSAOVERLAPPED structure (ignored for nonoverlapped sockets).
lpCompletionRoutine
[in] Pointer to the completion routine called when the operation has been completed (ignored for nonoverlapped sockets).
lpThreadId
[in] Pointer to a WSATHREADID 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
[out] Pointer to the error code.

Remarks

This routine is used to set or retrieve operating parameters associated with the socket, the transport protocol, or the communications subsystem. If both lpOverlapped and lpCompletionRoutine are NULL, the socket in this function will be treated as a nonoverlapped socket.

For nonoverlapped sockets, lpOverlapped and lpCompletionRoutine parameters are ignored and this function can block if socket s is in blocking mode. Note that if socket s is in nonblocking mode, this function can return WSAEWOULDBLOCK if the specified operation cannot be finished immediately. In this case, the Windows Sockets SPI client may change the socket to blocking mode and reissue the request or wait for the corresponding network event (such as FD_ROUTING_INTERFACE_CHANGE or FD_ADDRESS_LIST_CHANGE in case of SIO_ROUTING_INTERFACE_CHANGE or SIO_ADDRESS_LIST_CHANGE) using Windows message (through WSPAsyncSelect or event (using WSPEventSelect) based notification mechanism. For overlapped sockets, operations that cannot be completed immediately will be initiated and completion will be indicated at a later time. Final completion status is retrieved through WSPGetOverlappedResult.

Any IOCTL may block indefinitely, depending on the implementation of the service provider. If the Windows Sockets SPI client cannot tolerate blocking in a WSPIoctl call, overlapped I/O would be advised for ioctls that are most likely to block including:

Some protocol-specific ioctls may also be particularlly likely to block. Check the relevant protocol-specific annex for available information.

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 constructed 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.

I O V T Vendor/address family Code
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 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 that defines the type of IOCTL. The following values are defined:

0 The IOCTL is a standard Unix IOCTL code, as with FIONREAD and FIONBIO.

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 that appears in the Vendor/AddressFamily member. 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.

The Vendor/Address Family is an 11-bit quantity that defines the vendor who owns the code (if T == 3) or that contains the address family to which the code applies (if T == 2). If this is a Unix IOCTL code (T == 0) then this member has the same value as the code on Unix. If this is a generic Windows Sockets 2 IOCTL (T == 1) then this member can be used as an extension of the code member to provide additional code values.

Code The specific IOCTL code for the operation.

The following Unix commands are supported.

Parameters

FIONBIO
Enables or disables nonblocking mode on socket s. lpvInBuffer points at an unsigned long, which is nonzero if nonblocking mode is to be enabled and zero if it is to be disabled. When a socket is created, it operates in blocking mode (that is, nonblocking 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 Windows Sockets SPI client must first disable WSPAsyncSelect by calling WSPAsyncSelect with the lEvent parameter equal to zero, or disable WSPEventSelect by calling WSPEventSelect with the lNetworkEvents parameter equal to zero.

FIONREAD
Determines the amount of data that can be read atomically from socket s. lpvOutBuffer points at an unsigned long in which WSPIoctl stores the result. If s is stream oriented (for example, type SOCK_STREAM), FIONREAD returns the total amount of data that can 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 (for example, type SOCK_DGRAM), FIONREAD returns the size of the first datagram (message) queued on the socket.
SIOCATMARK
Determines whether or not all OOB data has been read. This applies only to a socket of stream style (for example, type SOCK_STREAM) that has been configured for inline reception of any OOB data (SO_OOBINLINE). If no OOB 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 Windows Sockets SPI client should use the SIOCATMARK operation to determine whether any remains. If there is any normal data preceding the urgent (OOB) data, it will be received in order. (Note that receive operations will never mix OOB and normal data in the same call.) lpvOutBuffer points at a BOOL in which WSPIoctl stores the result.

The following Windows Sockets 2 commands are supported.

Parameters

SIO_ASSOCIATE_HANDLE (opcode setting: I, T==1)
Associates 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 (for example, TH_NETDEV and TH_TAPI), followed by a value that 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 that do not support this IOCTL. The handle associated by this IOCTL can be retrieved using SIO_TRANSLATE_HANDLE.

A companion interface might be used, for example, if a particular provider provides:

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 that 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), that 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 that do not support this IOCTL.
SIO_GET_BROADCAST_ADDRESS (opcode setting: O, T==1)
This IOCTL fills the output buffer with a SOCKADDR structure containing a suitable broadcast address for use with WSPSendTo.
SIO_GET_EXTENSION_FUNCTION_POINTER (opcode setting: O, I, T==1)
Retrieves 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, T==1)
Retrieves the QOS structure associated with the socket. The input buffer is optional. Some protocols (for example, 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 structure. The WSAENOPROTOOPT error code is indicated for service providers that do not support quality of service.
SIO_GET_GROUP_QOS (opcode setting: O, T==1)
Reserved.
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 1 (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 can 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 that do not support quality of service.
SIO_SET_GROUP_QOS (opcode setting: I, T==1)
Reserved.
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 (for example, TH_NETDEV and TH_TAPI). 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 function. 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 that do not support this IOCTL for the specified companion interface. This IOCTL retrieves the handle associated using SIO_TRANSLATE_HANDLE.

It is recommended that COM be used instead of this IOCTL to discover and track other interfaces that might be supported by a socket. This IOCTL is present for backward compatibility with systems where COM is not available or cannot be used for some other reason.

SIO_ROUTING_INTERFACE_QUERY (opcode setting: I, O, T==1)
To obtain the address of the local interface (represented as SOCKADDR structure) that should be used to send to the remote address specified in the input buffer (as SOCKADDR). Remote multicast addresses may be submitted in the input buffer to get the address of the preferred interface for multicast transmission. In any case, the interface address returned may be used by the application in a subsequent bind request.

Note that routes are subject to change. Therefore, Windows Socket SPI clients cannot rely on the information returned by SIO_ROUTING_INTERFACE_QUERY to be persistent. SPI clients may register for routing change notifications using the SIO_ROUTING_INTERFACE_CHANGE IOCTL, which provides for notification through either overlapped I/O or a FD_ROUTING_INTERFACE_CHANGE event. The following sequence of actions can be used to guarantee that the Windows Socket SPI client always has current routing interface information for a given destination:

If output buffer is not large enough to contain the interface address, SOCKET_ERROR is returned as the result of this IOCTL and WSPGetLastError returns WSAEFAULT. The required size of the output buffer will be returned in lpcbBytesReturned in this case. Note the WSAEFAULT error code is also returned if the lpvInBuffer, lpvOutBuffer, or lpcbBytesReturned parameter is not totally contained in a valid part of the user address space.

If the destination address specified in the input buffer cannot be reached through any of the available interfaces, SOCKET_ERROR is returned as the result of this IOCTL and WSAGetLastError returns WSAENETUNREACH or even WSAENETDOWN if all of the network connectivity is lost.

SIO_ROUTING_INTERFACE_CHANGE (opcode setting: I, T==1)
To receive notification of the interface change that should be used to reach the remote address in the input buffer (specified as a SOCKADDR structure). No output information will be provided upon completion of this IOCTL; the completion merely indicates that the routing interface for a given destination has changed and should be queried again through SIO_ROUTING_INTERFACE_QUERY.

It is assumed (although not required) that the Windows Socket SPI client uses overlapped I/O to be notified of routing interface change through completion of SIO_ROUTING_INTERFACE_CHANGE request. Alternatively, if the SIO_ROUTING_INTERFACE_CHANGE IOCTL is issued on a nonblocking socket and without overlapped parameters (lpOverlapped / CompletionRoutine are set to NULL), it will complete immediately with error WSAEWOULDBLOCK and the Windows Socket SPI client can then wait for routing change events using a call to WSPEventSelect or WSPAsyncSelect with the FD_ROUTING_INTERFACE_CHANGE bit set in the network event bitmask.

It is recognized that routing information remains stable in most cases. So requiring the Windows Sockets SPI client to keep multiple outstanding IOCTLs—for notifications about all destinations that it is interested in as well as having the service provider keep track of all them—will unnecessarily tie up significant system resources. This situation can be avoided by extending the meaning of the input parameters and relaxing the service provider requirements as follows:

The Windows Sockets SPI client can specify a protocol family specific wildcard address (same as one used in bind call when requesting to bind to any available address) to request notifications of any routing changes. This allows the Windows Sockets SPI client to keep only one outstanding SIO_ROUTING_INTERFACE_CHANGE for all the sockets/destinations it has and then use SIO_ROUTING_INTERFACE_QUERY to get the actual routing information.

Service provider can opt to ignore the information supplied by the Windows Sockets SPI client in the input buffer of the SIO_ROUTING_INTERFACE_CHANGE (as though the Windows Sockets SPI client specified a wildcard address) and complete the SIO_ROUTING_INTERFACE_CHANGE IOCTL or signal FD_ROUTING_INTERFACE_CHANGE event in the event of any routing information change (not just the route to the destination specified in the input buffer).

SIO_ADDRESS_LIST_QUERY (opcode setting: I, O, T==1)
To obtain a list of local transport addresses of the socket's protocol family to which the Windows Sockets SPI client can bind. The list returned in the output buffer using the following format:
typedef struct _SOCKET_ADDRESS_LIST {
….INT iAddressCount;
….SOCKET_ADDRESS Address[1];
} SOCKET_ADDRESS_LIST, FAR * LPSOCKET_ADDRESS_LIST;
Members:
….iAddressCount- number of address structures in the list;
….Address- array of protocol family specific address structures.

Note that in Win32 Plug and Play environments, addresses can be added and removed dynamically. Therefore, Windows Sockets SPI clients cannot rely on the information returned by SIO_ADDRESS_LIST_QUERY to be persistent. Windows Sockets SPI clients may register for address change notifications through the SIO_ADDRESS_LIST_CHANGE IOCTL that provides for notification through either overlapped I/O or FD_ADDRESS_LIST_CHANGE event. The following sequence of actions can be used to guarantee that the Windows Sockets SPI client always has current address list information:

If the output buffer is not large enough to contain the address list, SOCKET_ERROR is returned as the result of this IOCTL and WSPGetLastError returns WSAEFAULT. The required size of the output buffer will be returned in lpcbBytesReturned in this case. Note the WSAEFAULT error code is also returned if the lpvInBuffer, lpvOutBuffer, or lpcbBytesReturned parameter is not totally contained in a valid part of the user address space.

SIO_ADDRESS_LIST_CHANGE (opcode setting: T==1)
To receive notification of changes in the list of local transport addresses of the socket's protocol family to which the Windows Sockets SPI client can bind. No output information will be provided upon completion of this IOCTL; the completion merely indicates that the list of available local addresses has changed and should be queried again through SIO_ADDRESS_LIST_QUERY.

It is assumed (although not required) that the Windows Sockets SPI client uses overlapped I/O to be notified of change by completion of SIO_ADDRESS_LIST_CHANGE request. Alternatively, if the SIO_ADDRESS_LIST_CHANGE IOCTL is issued on a nonblocking socket and without overlapped parameters (lpOverlapped and lpCompletionRoutine are set to NULL), it will complete immediately with error WSAEWOULDBLOCK. The Windows Sockets SPI client can then wait for address list change events through a call to WSPEventSelect or WSPAsyncSelect with the FD_ADDRESS_LIST_CHANGE bit set in the network event bitmask.

SIO_QUERY_PNP_TARGET_HANDLE (opcode setting: O, T==1)
To obtain the socket descriptor of the next provider in the chain on which the current socket depends in PnP sense. This IOCTL is invoked by the Windows Sockets 2 DLL only on sockets of non-IFS service providers created through WPUCreateSocketHandle call. The provider should return in the output buffer the socket handle of the next provider in the chain on which a given socket handle depends in PnP sense (for example, the removal of the device that supports the underlying handle will result in the invalidation of the handle above it in the chain).

If an overlapped operation completes immediately, this function returns a value of zero and the lpcbBytesReturned parameter is updated with the number of bytes in the output buffer. If the overlapped operation is successfully initiated and will complete later, this function returns SOCKET_ERROR and indicates error code WSA_IO_PENDING. In this case, lpcbBytesReturned is not updated. When the overlapped operation completes, the amount of data in the output buffer is indicated either through the cbTransferred parameter in the completion routine (if specified), or through the lpcbTransfer parameter in WSPGetOverlappedResult.

When called with an overlapped socket, the lpOverlapped parameter must be valid for the duration of the overlapped operation. 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 member of lpOverlapped when the overlapped operation completes if it contains a valid event object handle. The Windows Sockets SPI client can use WSPGetOverlappedResult to poll or wait on the event object.

If lpCompletionRoutine is not NULL, the hEvent member is ignored and can be used by the Windows Sockets SPI client to pass context information to the completion routine. A client that passes a non-NULL lpCompletionRoutine and later calls WSAGetOverlappedResult for the same overlapped I/O request may not set the fWait parameter for that invocation of WSAGetOverlappedResult to TRUE. In this case, the usage of the hEvent member is undefined, and attempting to wait on the hEvent member would produce unpredictable results.

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 Ws2_32.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 and process context by calling WPUQueueApc. This function can be called from any process and thread context, even a context different from the thread and process that was used to initiate the overlapped operation.

WPUQueueApc takes as input parameters a pointer to a WSATHREADID structure (supplied to the provider through 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 itself cannot be the client specified–completion routine. The service provider must instead supply a pointer to its own APC function that 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. The dwError specifies the completion status for the overlapped operation as indicated by lpOverlapped. The cbTransferred specifies the number of bytes returned. Currently, there are no flag values defined and dwFlags will be zero. This function does not return a value.

Returning from this function allows invocation of another pending completion routine for this socket. The completion routines can be called in any order, though not necessarily in the same order that the overlapped operations are completed.

Compatibility

The IOCTL codes with T == 0 are a subset of the IOCTL codes used in Berkeley sockets. In particular, there is no command that is equivalent to FIOASYNC.

Return Values

If no error occurs and the operation has completed immediately, WSPIoctl returns zero. 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.

Error Codes

Error code Meaning
WSAENETDOWN Network subsystem has failed.
WSAEFAULT The lpvInBuffer, lpvOutBuffer or lpcbBytesReturned argument is not totally contained in a valid part of the user address space, or the cbInBuffer or cbOutBuffer argument is too small.
WSAEINVAL The dwIoControlCode is not a valid command, or a supplied input parameter is not acceptable, or the command is not applicable to the type of socket supplied.
WSAEINPROGRESS Function is invoked when a callback is in progress.
WSAENOTSOCK Descriptor s is not a socket.
WSAEOPNOTSUPP Specified IOCTL command cannot be realized. For example, the flow specifications specified in SIO_SET_QOS cannot be satisfied.
WSA_IO_PENDING An overlapped operation was successfully initiated and completion will be indicated at a later time.
WSAEWOULDBLOCK Socket is marked as nonblocking and the requested operation would block.

Requirements

  Version: Requires Windows Sockets 2.0.
  Header: Declared in Ws2spi.h.

See Also

WSPSocket, WSPSetSockOpt, WSPGetSockOpt, WPUQueueApc