3

The WSARecvMsg function as described here requires that you retrieve a function pointer to it as shown in the following quote:

Note The function pointer for the WSARecvMsg function must be obtained at run time by making a call to the WSAIoctl function with the SIO_GET_EXTENSION_FUNCTION_POINTER opcode specified.

Is there a specific reason for this? In the use of this function I intend to retrieve the function pointer at boot time then use it consistently from then on. Is there anything wrong with this approach? Can anything about the function change which would mean we need to re-acquire this pointer and how can we know if this is the case?

Fantastic Mr Fox
  • 32,495
  • 27
  • 95
  • 175
  • 1
    Seems like a terrible design idea from MSFT. I do not see any benefits in it. – SergeyA May 20 '16 at 21:25
  • @SergeyA My only thoughts are maybe changes in the hardware or something can change this function??? But the documentation doesn't reference anything like this so i am not sure. – Fantastic Mr Fox May 20 '16 at 21:28
  • my only very wild guess that the function was added at some point when the library public protocol was finalized, and no one wanted to risk adding additional function to it. Instead, they decided to piggy-back on something which already existed, and this terrible solution stayed. I am pretty sure the value returned by this function will always be the same. – SergeyA May 20 '16 at 21:33
  • @SergeyA God it would be nice if they documented this ... – Fantastic Mr Fox May 20 '16 at 21:36
  • you might want to ask them? There are some venues, I suppose? (sorry, I am not much of MSFT developer) – SergeyA May 20 '16 at 21:37
  • It shouldn't change after the process is loaded and `WSAStartup()` has been called. – user207421 May 20 '16 at 23:12

1 Answers1

19

Per the WSARecvMsg() documentation:

Note This function is a Microsoft-specific extension to the Windows Sockets specification

Per the WSAIoctrl() documentation:

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 globally unique identifier (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.

On most systems, Microsoft's provider is the only provider installed. However, 3rd party providers do exist (custom TCP stacks, etc) and may be installed as well. Per the WSADATA documentation for WSAStartup():

the architecture of Windows Sockets changed in version 2 to support multiple providers, and WSADATA no longer applies to a single vendor's stack.

Which is further backed by:

Windows Sockets 2 Architecture

Provider-Specific Extension Mechanism

When you create a socket using socket(), you don't have any control over which provider is used. When you create a socket using WSASocket() instead, you can optionally specify a specific provider via the lpProtocolInfo parameter.

WSARecvMsg() is only available in Microsoft's provider, and as such you must pass it a SOCKET that is associated with the same provider. WSAIoctrl() can be used to send commands to the provider that a SOCKET belongs to. So, by using SIO_GET_EXTENSION_FUNCTION_POINTER, you ensure that WSARecvMsg() (or any other vendor-specific function) is supported by the provider of the specified SOCKET and thus is compatible with that SOCKET.

The other Microsoft-specific functions that are provided by Microsoft's provider via WSAIoctrl()1 are:

  • AcceptEx()
  • ConnectEx()
  • DisconnectEx()
  • GetAcceptExSockAddrs()
  • TransmitFile()
  • TransmitPackets()
  • WSASendMsg()

Once you have retrieved a pointer to a vendor-specific function, you can reuse the pointer as much as you want as long as the provider stays loaded in memory (between the first call to WSAStartup() and the last call to WSACleanup()) and you pass it a SOCKET that belongs to that provider.

1: Per Provider-Specific Extension Mechanism

On Windows Vista and later, new Winsock system extensions are exported directly from the Winsock DLL, so the WSAIoctl function is not needed to load these extensions. The new extension functions available on Windows Vista and later include the WSAPoll and WSASendMsg functions that are exported from Ws2_32.dll.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770