0

In Visual Studio 2015 on Windows 10, I am getting the error error C3861: 'DisconnectEx': identifier not found. According to documentation on DisconnectEx, the function is defined in the header mswsock.h, but including that header does not work. Did the definition move elsewhere? Is there a mistake in the documentation?

Joe
  • 2,008
  • 1
  • 17
  • 25
  • Read the Note in the MSDN article: "The function pointer for the DisconnectEx function must be obtained at run time ...". Declare the function pointer as LPFN_DISCONNECTEX. – Hans Passant Apr 19 '16 at 00:33
  • Related: [Where is ConnectEx defined?](http://stackoverflow.com/questions/10967516/) – Remy Lebeau Apr 19 '16 at 01:14

1 Answers1

1

The DisconnectEx() function itself is not declared in mswsock.h. Read the documentation again more carefully:

Note The function pointer for the DisconnectEx function must be obtained at run time by making a call to the WSAIoctl function with the SIO_GET_EXTENSION_FUNCTION_POINTER opcode specified. The input buffer passed to the WSAIoctl function must contain WSAID_DISCONNECTEX, a globally unique identifier (GUID) whose value identifies the DisconnectEx extension function. On success, the output returned by the WSAIoctl function contains a pointer to the DisconnectEx function. The WSAID_DISCONNECTEX GUID is defined in the Mswsock.h header file.

For example:

SOCKET s = ...;

...

GUID guidDisconnectEx = WSAID_DISCONNECTEX;
LPFN_DISCONNECTEX lpDisconnectEx = NULL;
DWORD cbBytesReturned = 0;    
WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &guidDisconnectEx, sizeof(guidDisconnectEx), &lpDisconnectEx, sizeof(lpDisconnectEx), &cbBytesReturned, NULL, NULL);

...

if (lpDisconnectEx)
    lpDisconnectEx(s);
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • I'm confused why the socket `s` has to be passed into `WSAIoctl`. Can `DisconnectEx` only be called on that socket or can I disconnect other sockets also? – Joe Apr 19 '16 at 00:59
  • `DisconnectEx()` is a provider-specific extension, it is not part of the base Winsock API. By passing in a `SOCKET` handle, `WSAIoctl()` can query the function pointer from the provider that created the socket object. To use `DisconnectEx()`, the socket has to be created by Microsoft's WinSock2 provider, hence the note in the documentation: "*This function is a **Microsoft-specific extension** to the Windows Sockets specification*". There are other 3rd party socket providers in use in the world. – Remy Lebeau Apr 19 '16 at 01:05
  • Using WinSock/2 on Windows *usually* uses Microsoft's provider (it is the default provider). But to *guarantee* that Microsoft's provider is used, if other providers are installed, you can request it via the `ProviderId` field of the [`WSAPROTOCOL_INFO`](https://msdn.microsoft.com/en-us/library/windows/desktop/ms741675.aspx) passed to [`WSASocket()`](https://msdn.microsoft.com/en-us/library/windows/desktop/ms742212.aspx). [`WSAEnumProtocols()`](https://msdn.microsoft.com/en-us/library/windows/desktop/ms741574.aspx) can enumerate the available providers and their implemented protocols. – Remy Lebeau Apr 19 '16 at 01:17
  • You can call `DisconnectEx()` on *any* socket that is created with the Microsoft provider, but you need to start with a socket from that same provider in order to obtain the function pointer. You can use a temporary socket, if you want. *Some* `WSAIoctl()` controls allow `INVALID_SOCKET` to be specified, but AFAIK `SIO_GET_EXTENSION_FUNCTION_POINTER` is not one of them. – Remy Lebeau Apr 19 '16 at 01:25