Compartilhar via


WSPIoctl function

WSPIoctl sets or retrieves operating parameters associated with a socket.

Syntax

int 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
);

Parameters

  • s [in]
    Descriptor that identifies a socket.

  • dwIoControlCode [in]
    Control code of the operation to perform.

  • lpvInBuffer [in]
    Pointer to an input buffer that contains information for the SAN service provider.

  • cbInBuffer [in]
    Size, in bytes, of the input buffer at lpvInBuffer.

  • lpvOutBuffer [out]
    Pointer to an output buffer that receives information from the SAN service provider.

  • cbOutBuffer [in]
    Size, in bytes, of the output buffer at lpvOutBuffer.

  • lpcbBytesReturned [out]
    Pointer to a variable that receives the size, in bytes, of the output buffer at lpvOutBuffer on return.

  • lpOverlapped [in]
    Pointer to a WSAOVERLAPPED structure. Ignored for nonoverlapped sockets.

  • lpCompletionRoutine [in]
    Pointer to the completion routine that the SAN service provider might initiate after the operation completes. Ignored for nonoverlapped sockets. This completion routine is defined as CompletionRoutine.

  • lpThreadId [in]
    Pointer to a WSATHREADID structure that the SAN service provider uses in a subsequent call to the WPUQueueApc function to arrange for the execution of the completion routine at lpCompletionRoutine. A WSATHREADID structure identifies a thread. The SAN service provider should store the referenced WSATHREADID structure (not the pointer to same) until after WPUQueueApc returns. For more information about WPUQueueApc, see the Microsoft Windows SDK documentation.

  • lpErrno [out]
    Pointer to a variable that receives the error code.

Return value

Returns zero if successful and the operation completed immediately; otherwise returns SOCKET_ERROR and, at lpErrno, one of the following error codes:

Return code Description
WSAENETDOWN

Network subsystem failed.

WSAEFAULT

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

WSAEINVAL

Control code in dwIoControlCode is not a valid code, a supplied input parameter is not acceptable, or the control code is not applicable to the type of socket supplied.

WSAENOTSOCK

Descriptor is not a socket.

WSAEOPNOTSUPP

Operation specified by the control code in dwIoControlCode cannot be realized. For example, a SAN service provider returns this error if it does not support the flow specifications specified in the QoS structure at lpvInBuffer for the SIO_SET_QOS control code.

WSAENOPROTOOPT

Operation or feature is unsupported by the SAN service provider.

WSA_IO_PENDING

SAN service provider successfully initiated an overlapped operation and will indicate completion at a later time.

WSAEWOULDBLOCK

Socket is marked as nonblocking and the requested operation cannot be completed immediately (that is, the operation would block and must be performed asynchronously).

 

Note that a SAN service provider does not support the WSAEINPROGRESS error code for WSPIoctl because the switch never issues cancel blocking calls to a SAN service provider.

Note that if WSPIoctl returns zero and the operation completed immediately, the completion routine, if specified, will have already been queued.

Remarks

CompletionRoutine

void CALLBACK
  CompletionRoutine(
 IN DWORD dwError,
 IN DWORD cbTransferred,
 IN LPWSAOVERLAPPED lpOverlapped,
 IN DWORD dwFlags
 );

The parameters of this completion routine are defined as:

  • dwError
    Completion status for the overlapped operation at lpOverlapped.

  • cbTransferred
    Number of bytes transferred during the overlapped operation.

  • lpOverlapped
    Pointer to the WSAOVERLAPPED structure that the switch passed for the overlapped operation.

  • dwFlags
    Set of flags for the overlapped operation. Currently none are defined.

The Windows Sockets switch calls a SAN service provider's WSPIoctl function to set or retrieve operating parameters associated with a socket.

A call to WSPIoctl using any supported input/output control (IOCTL) code might block indefinitely, depending on the SAN service provider's implementation. Because the switch cannot tolerate blocking in some WSPIoctl calls, it uses overlapped I/O for IOCTL codes that are especially likely to block, including the following supported IOCTL codes:

  • SIO_GET_QOS

  • SIO_GET_GROUP_QOS

  • SIO_SET_QOS

  • SIO_SET_GROUP_QOS

Note   If socket S is in nonblocking mode, WSPIoctl returns the WSAEWOULDBLOCK error code if the SAN service provider cannot finish the specified operation immediately. In this case, the Windows Sockets switch must change the socket to blocking mode and reissue the request.

 

Because IOCTL codes are 32-bit entities, the following encoding scheme partitions the identifier space for each IOCTL code so vendors can add new IOCTL codes. Each column in the following table specifies the number of bits in each partition of an IOCTL-code.

I O V T Vendor/address family IOCTL code

1

1

1

2

11

16 maximum

 

  • I
    A single-bit quantity that is set if the input buffer is valid for the IOCTL code, as with IOC_IN.

  • O
    A single-bit quantity that is set if the output buffer is valid for the IOCTL code, as with IOC_OUT.

  • V
    A single-bit quantity that is set if there are no parameters for the IOCTL code, as with IOC_VOID.

  • T
    A two-bit quantity that defines the type of IOCTL code. The following values are defined:

    • 00
      The IOCTL code is a standard Unix IOCTL code, as with FIONREAD, FIONBIO, and so on.

    • 01
      The IOCTL code is a generic Windows Sockets 2 IOCTL code. New IOCTL codes defined for Windows Sockets 2 have T== 01.

    • 10
      The IOCTL code applies only to a specific address family.

    • 11
      The IOCTL code applies only to a specific SAN service provider. This type allows vendors to be assigned a number that appears in the Vendor/address family field. With a vendor number assigned, the vendor has the flexibility and privacy to define new IOCTL codes without having to register those IOCTL codes with a clearinghouse.

  • Vendor/address family
    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 the IOCTL code is a standard Unix IOCTL code ( T== 0), this field has the same value as the code on Unix. If this is a generic Windows Sockets 2 IOCTL code ( T== 1), this field can be used as an extension of the IOCTL-code field to provide additional code values.

  • IOCTL Code
    The specific IOCTL code for the operation. The IOCTL code can be up to a 16-bit quantity.

    Note   IOCTL codes that set both I and O partitions indicate that both input and output buffers are valid.

     

Supported IOCTL Codes for SAN Service Providers

SAN service providers support the following Windows Sockets IOCTL codes. The Windows Sockets switch issues these IOCTL codes either for its own internal purposes or on behalf of an application.

  • SIO_GET_EXTENSION_FUNCTION_POINTER
    Partition settings: O==1(set), I==1(set), T==01

    Retrieves a pointer to an extension function that a SAN service provider must support. For more information about extension functions, see Windows Sockets SPI Extensions for SANs. The input buffer of the WSPIoctl call contains the GUID whose value identifies the specified extension function. The SAN service provider returns the pointer to the requested function in the WSPIoctl function's output buffer. The following table contains GUIDs for extension functions that a SAN service provider can support.

    Extension Function GUID

    WSPRegisterMemory

    {C0B422F5-F58C-11d1-AD6C-00C04FA34A2D}

    WSPDeregisterMemory

    {C0B422F6-F58C-11d1-AD6C-00C04FA34A2D}

    WSPRegisterRdmaMemory

    {C0B422F7-F58C-11d1-AD6C-00C04FA34A2D}

    WSPDeregisterRdmaMemory

    {C0B422F8-F58C-11d1-AD6C-00C04FA34A2D}

    WSPRdmaWrite

    {C0B422F9-F58C-11d1-AD6C-00C04FA34A2D}

    WSPRdmaRead

    {C0B422FA-F58C-11d1-AD6C-00C04FA34A2D}

    WSPMemoryRegistrationCacheCallback

    {E5DA4AF8-D824-48CD-A799-6337A98ED2AF}

     

  • SIO_GET_QOS
    Partition settings: O==1(set), I==1(set), T==01

    If a SAN service provider supports quality of service (QoS), retrieves the QoS structure associated with the socket. The input buffer is optional. Some protocols, such as RSVP, require the input buffer to qualify a QoS request. The SAN service provider copies the QoS structure into the output buffer. The switch must allocate enough space for the output buffer to hold the full QoS structure.

    The SAN service provider returns the WSAENOPROTOOPT error code if it does not support QoS.

  • SIO_GET_GROUP_QOS
    Partition settings: O==1(set), I==1(set), T==01

    This IOCTL code is reserved for future use with socket groups. The switch currently ignores it.

    If a SAN service provider supports QoS, retrieves the QoS structure associated with the socket group to which this socket belongs. The input buffer is optional. Some protocols, such as RSVP, require the input buffer to qualify a QoS request. The SAN service provider copies the QoS structure into the output buffer. If the socket that was specified in the WSPIoctl call does not belong to an appropriate socket group, the SAN service provider sets the SendingFlowspec and ReceivingFlowspec members of the QoS structure to NULL.

    The SAN service provider returns the WSAENOPROTOOPT error code if it does not support QoS.

  • SIO_SET_QOS
    Partition settings: O==0(not set), I==1(set), T==01

    If a SAN service provider supports QoS, associates the supplied QoS structure with the socket. The switch does not require an output buffer; the SAN service provider retrieves the QoS structure from the input buffer.

    The SAN service provider returns the WSAENOPROTOOPT error code if it does not support QoS.

  • SIO_SET_GROUP_QOS
    Partition settings: O==0(not set), I==1(set), T==01

    This IOCTL code is reserved for future use with socket groups. The switch currently ignores it.

    If a SAN service provider supports QoS, establishes the supplied QoS structure with the socket group to which this socket belongs. The switch does not require an output buffer; the SAN service provider retrieves the QoS structure from the input buffer.

    The SAN service provider returns the WSAENOPROTOOPT error code if it does not support QoS or if the specified socket descriptor is not the creator of the associated socket group.

  • SIO_ADDRESS_LIST_QUERY
    Partition settings: O==1(set), I==1(set), T==01

    Retrieves a list of local IP addresses that are assigned to the network interface cards (NICs) that the SAN service provider services. The SAN service provider uses a SOCKET_ADDRESS_LIST structure, defined as follows, to return the list in the output buffer.

    typedef struct _SOCKET_ADDRESS_LIST {
      INT  iAddressCount; 
      SOCKET_ADDRESS  Address[1]; 
    } SOCKET_ADDRESS_LIST, FAR * LPSOCKET_ADDRESS_LIST;
    

    The members of this structure contain the following information:

    • iAddressCount
      Specifies the number of address structures in the list.

    • Address
      Array of IP address structures.

    The switch supports both the IPv4 and IPv6 protocols. If the SAN service provider supports the IPv6 protocol, it returns the IPv6 addresses that it supports. When returning IPv6 addresses, the SAN service provider specifies an address family of AF_INET6. A SAN service provider can return the following types of IPv6 addresses:

    • Unicast IPv6 addresses

    • Native IPv6 addresses, including link local, site local, and global addresses

    A SAN support should not return the following types of IPv6 addresses:

    • Temporary IPv6 addresses

    • Any IPv4-compatible IPv6 addresses, including:

      • IPv4-compatible address (0:0:0:0:0:0:w.x.y.z - w.x.y.z is a v4 address)
      • IPv4-mapped address (0:0:0:0:0:FFFF:w.x.y.z)
      • 6-over-4 address (FE80::0:0:WWXX:YYZZ)
      • 6-to-4 address (2002:WWXX:YYZZ:[SLA ID]:[Interface ID])
      • ISATAP address ( [64 bit prefix]:0:5EFE:w.x.y.z )

    The switch uses the SIO_ADDRESS_LIST_QUERY IOCTL code to determine whether to use a given SAN service provider for making connections or listening for incoming connections. The switch forwards actual application requests for the list of local IP addresses to the TCP/IP provider. The switch also uses the SIO_ADDRESS_LIST_CHANGE IOCTL code with the TCP/IP service provider to detect changes in address lists that all SAN service providers service. After TCP/IP reports a change, through either overlapped I/O or the FD_ADDRESS_LIST_CHANGE event, the switch uses the SIO_ADDRESS_LIST_QUERY IOCTL code to query all SAN service providers to refresh their lists. If the output buffer is not large enough to contain the address list, the SAN service provider returns SOCKET_ERROR and, at lpErrno, the WSAEFAULT error code. The SAN service provider also returns the size of the output buffer that it requires in the variable at lpcbBytesReturned.

The switch always makes a blocking WSPIoctl call using the SIO_GET_EXTENSION_POINTER and SIO_ADDRESS_LIST_QUERY IOCTL codes. That is, the switch does not use overlapped I/O. However, the switch makes a nonblocking WSPIoctl call using the SIO_GET_QOS and SIO_SET_QOS IOCTL codes and any completion method that the overlying application specifies. The following paragraphs discuss SAN service provider requirements regarding completion of overlapped WSPIoctl calls.

Overlapped Socket I/O

If the switch specifies NULL for a completion routine, the SAN service provider should call the WPUCompleteOverlappedRequest function in the context of an arbitrary thread to complete the request. Either the switch or the Windows Sockets DLL can intercept the WPUCompleteOverlappedRequest call. After intercepting this call, the intercepting entity uses the notification mechanism that was requested by the application to signal completion of the request. This notification mechanism can be an event or a completion port. The switch specifies an overlapped structure and NULL for a completion routine to issue most requests. However, requests from applications for the switch to forward QoS information directly to a SAN service provider can use any completion notification mechanism. If a SAN service provider does not support QoS, this situation should never arise.

If the low order bit of the hEvent member in the WSAOVERLAPPED structure is set, an application or the switch specifically requests to not be notified with a completion port. If the remainder of hEvent is NULL as well, excluding the low order bit, the SAN service provider can assume that the I/O request requires no completion notification. In this case, the calling entity calls the WSPGetOverlappedResult function to poll for completion. For more information, see the CreateIoCompletionPort and GetQueuedCompletionStatus functions in the Microsoft Windows SDK documentation.

If the switch specifies a non-NULL completion routine, the SAN service provider ignores the hEvent member in the WSAOVERLAPPED structure. Therefore, the switch can use hEvent to pass context information to the completion routine. An application that initiates a request with a non-NULL completion routine and later calls the WSAGetOverlappedResult function for that request cannot specify that the WSAGetOverlappedResult call wait for the request to complete. That is, the application cannot specify TRUE for the fWait parameter in the WSAGetOverlappedResult call. In this case, usage of hEvent is undefined, and attempting to wait for hEvent produces unpredictable results.

If the switch forwards a request, along with a non-NULL completion routine, in the WSPIoctl call, the SAN service provider must initiate the completion routine after the request completes. Because the completion routine must be executed in the context of the same thread that initiated the request, the SAN service provider cannot directly call the completion routine. The Windows Sockets interface offers an asynchronous procedure call (APC) mechanism to facilitate invocation of completion routines. This APC mechanism is the WPUQueueApc function. A SAN service provider calls WPUQueueApc to arrange for the execution of a completion routine in the proper thread and process context. The SAN service provider can call WPUQueueApc from any process and thread context, even a context different from the thread and process used to initiate the request.

The SAN service provider passes to WPUQueueApc the pointer to the WSATHREADID structure that the switch supplied in the WSPIoctl call. The SAN service provider also passes to WPUQueueApc 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 be the original completion routine. Rather, the SAN service provider must supply a pointer to its own APC function. This APC function uses the supplied context value to access the required result information for the original request and then calls the original completion routine.

For more information about WSAGetOverlappedResult, WPUCompleteOverlappedRequest, and WPUQueueApc, see the Windows SDK documentation.

Requirements

Target platform

Desktop

Version

Requires Windows Sockets version 2.0.

Header

Ws2spi.h (include Ws2spi.h)

See also

WSAOVERLAPPED

WSATHREADID

WSPDeregisterMemory

WSPDeregisterRdmaMemory

WSPGetOverlappedResult

WSPMemoryRegistrationCacheCallback

WSPRdmaRead

WSPRdmaWrite

WSPRegisterMemory

WSPRegisterRdmaMemory

WSPSocket

 

 

Send comments about this topic to Microsoft