in ctl/ctSocketExtensions.hpp [45:168]
static BOOL CALLBACK SocketExtensionInitFn(_In_ PINIT_ONCE, _In_ PVOID, _In_ PVOID*) noexcept
{
WSADATA wsadata;
if (::WSAStartup(WINSOCK_VERSION, &wsadata) != 0)
{
return FALSE;
}
auto wsaCleanupOnExit = wil::scope_exit([&]() noexcept { ::WSACleanup(); });
// check to see if need to create a temp socket
const auto localSocket = ::socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
if (INVALID_SOCKET == localSocket)
{
return FALSE;
}
auto closesocketOnExit = wil::scope_exit([&]() noexcept { ::closesocket(localSocket); });
// control code and the size to fetch the extension function pointers
for (auto fnLoop = 0ul; fnLoop < c_functionPtrCount; ++fnLoop)
{
VOID* functionPtr{nullptr};
DWORD controlCode{SIO_GET_EXTENSION_FUNCTION_POINTER};
DWORD bytes{sizeof(VOID*)};
// must declare GUID explicitly at a global scope as some commonly used test libraries
// - incorrectly pull it into their own namespace
GUID guid{};
switch (fnLoop)
{
case 0:
{
functionPtr = &g_transmitfile;
constexpr GUID tmpGuid = WSAID_TRANSMITFILE;
memcpy(&guid, &tmpGuid, sizeof GUID);
break;
}
case 1:
{
functionPtr = &g_acceptex;
constexpr GUID tmpGuid = WSAID_ACCEPTEX;
memcpy(&guid, &tmpGuid, sizeof GUID);
break;
}
case 2:
{
functionPtr = &g_getacceptexsockaddrs;
constexpr GUID tmpGuid = WSAID_GETACCEPTEXSOCKADDRS;
memcpy(&guid, &tmpGuid, sizeof GUID);
break;
}
case 3:
{
functionPtr = &g_transmitpackets;
constexpr GUID tmpGuid = WSAID_TRANSMITPACKETS;
memcpy(&guid, &tmpGuid, sizeof GUID);
break;
}
case 4:
{
functionPtr = &g_connectex;
constexpr GUID tmpGuid = WSAID_CONNECTEX;
memcpy(&guid, &tmpGuid, sizeof GUID);
break;
}
case 5:
{
functionPtr = &g_disconnectex;
constexpr GUID tmpGuid = WSAID_DISCONNECTEX;
memcpy(&guid, &tmpGuid, sizeof GUID);
break;
}
case 6:
{
functionPtr = &g_wsarecvmsg;
constexpr GUID tmpGuid = WSAID_WSARECVMSG;
memcpy(&guid, &tmpGuid, sizeof GUID);
break;
}
case 7:
{
functionPtr = &g_wsasendmsg;
constexpr GUID tmpGuid = WSAID_WSASENDMSG;
memcpy(&guid, &tmpGuid, sizeof GUID);
break;
}
case 8:
{
functionPtr = &g_rioextensionfunctiontable;
constexpr GUID tmpGuid = WSAID_MULTIPLE_RIO;
::memcpy(&guid, &tmpGuid, sizeof GUID);
controlCode = SIO_GET_MULTIPLE_EXTENSION_FUNCTION_POINTER;
bytes = {sizeof g_rioextensionfunctiontable};
::ZeroMemory(&g_rioextensionfunctiontable, bytes);
g_rioextensionfunctiontable.cbSize = bytes;
break;
}
default:
FAIL_FAST_MSG("Unknown ctSocketExtension function number");
}
if (0 != ::WSAIoctl(
localSocket,
controlCode,
&guid,
static_cast<DWORD>(sizeof guid),
functionPtr,
bytes,
&bytes,
nullptr, // lpOverlapped
nullptr))
{
if (WSAGetLastError() == WSAEOPNOTSUPP && 8 == fnLoop)
{
// ignore not-supported errors for RIO APIs to support Win7
}
else
{
return FALSE;
}
}
}
return TRUE;
}