Compartilhar via


WSPIoctl (Compact 2013)

3/26/2014

This function controls the mode of a socket.

Syntax

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 to determine the thread to run.
  • lpErrno
    [out] Pointer to the error code.

Remarks

This function 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 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 the IOCTLs that are most likely to block. The following list shows these IOCTLs:

  • SIO_ROUTING_INTERFACE_CHANGE
  • SIO_ADDRESS_LIST_CHANGE

Some protocol-specific IOCTLs may also be particularly 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.

  • 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 Berkeley Software Distribution (BSD) sockets.

    The WSPEventSelect routine automatically sets a socket to nonblocking mode. If 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 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 typically 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.

The following Windows Sockets 2 commands are supported.

  • 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_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_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:

    1. Issue SIO_ROUTING_INTERFACE_CHANGE IOCTL.
    2. Issue SIO_ROUTING_INTERFACE_QUERY IOCTL.
    3. Whenever SIO_ROUTING_INTERFACE_CHANGE IOCTL notifies the WinSock SPI client of routing change (either through overlapped I/O or by signaling FD_ROUTING_INTERFACE_CHANGE event), the whole sequence of actions should be repeated.

    If output buffer is not large enough to contain the interface address, SOCKET_ERROR is returned as the result of this IOCTL. 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.

  • 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 on 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.

    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 described below.

    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 will use the format in the following code sample.

    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:

    1. Issue SIO_ADDRESS_LIST_CHANGE IOCTL.
    2. Issue SIO_ADDRESS_LIST_QUERY IOCTL.
    3. Whenever SIO_ADDRESS_LIST_CHANGE IOCTL notifies the Windows Sockets SPI client of address list change (either through overlapped I/O or by signaling FD_ADDRESS_LIST_CHANGE event), the whole sequence of actions should be repeated.
      If the output buffer is not large enough to contain the address list, SOCKET_ERROR is returned as the result of this IOCTL. 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 on 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.

When called with an overlapped socket, the lpOverlapped parameter must be valid for the duration of the overlapped operation. The following code sample shows the WSAOVERLAPPED structure format.

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. Because 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 following code sample shows the prototype for the client-supplied completion routine.

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 Value

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.

The following table shows the possible error codes.

Error value

Description

WSAENETDOWN

Network subsystem has failed.

WSAEFAULT

The lpvInBuffer, lpvOutBuffer or lpcbBytesReturned parameter is not totally contained in a valid part of the user address space, or the cbInBuffer or cbOutBuffer parameter is too small.

WSAEINVAL

The dwIoControlCode is not a valid command, or asupplied 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.

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

Header

ws2spi.h

Library

Ws2.lib

See Also

Reference

Winsock SPI Functions
WSPSocket
WSPSetSockOpt
WSPGetSockOpt