461 lines
14 KiB
C++
461 lines
14 KiB
C++
//+---------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1997.
|
|
//
|
|
// File: T C P R S V P . C P P
|
|
//
|
|
// Contents: RSVP portion of TCP/IP
|
|
//
|
|
// Notes:
|
|
//
|
|
// Author: kumarp 19-March-98
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#include "pch.h"
|
|
#pragma hdrstop
|
|
#include "ncnetcfg.h"
|
|
#include <ws2spi.h>
|
|
#include "ncsvc.h"
|
|
|
|
const GUID c_guidRsvpNtName = { /* 9d60a9e0-337a-11d0-bd88-0000c082e69a */
|
|
0x9d60a9e0,
|
|
0x337a,
|
|
0x11d0,
|
|
{0xbd, 0x88, 0x00, 0x00, 0xc0, 0x82, 0xe6, 0x9a}
|
|
};
|
|
|
|
|
|
static const WCHAR* c_szChainNameUdp = L"RSVP UDP Service Provider";
|
|
static const WCHAR* c_szChainNameTcp = L"RSVP TCP Service Provider";
|
|
|
|
static const WCHAR* c_szRsvpFullPath = L"%SystemRoot%\\system32\\rsvpsp.dll";
|
|
|
|
// ----------------------------------------------------------------------
|
|
//
|
|
// Function: HrInstallRsvpProvider
|
|
//
|
|
// Purpose: This registers with winsock the RSVP TCP and UDP provider.
|
|
// This allows QoS for TCP and UDP
|
|
//
|
|
// Arguments: None
|
|
//
|
|
// Returns: S_OK on success, otherwise an error code
|
|
//
|
|
// Author: kumarp 19-March-98
|
|
//
|
|
// Notes: This function was written mainly by cwill.
|
|
//
|
|
HRESULT HrInstallRsvpProvider(VOID)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
INT err = 0;
|
|
INT result = 0;
|
|
WSAPROTOCOL_INFO awpiRsvp[2];
|
|
|
|
// Note: CWill : 08/08/97 : This is a hack to get TCP/IP
|
|
// registered before RSVP. We have to get some way
|
|
// of ordering RSVP after TCP/IP
|
|
(VOID) HrRunWinsock2Migration();
|
|
|
|
//
|
|
// Setup the UDP provider
|
|
//
|
|
|
|
awpiRsvp[0].dwServiceFlags1 =
|
|
XP1_QOS_SUPPORTED
|
|
| XP1_CONNECTIONLESS
|
|
| XP1_MESSAGE_ORIENTED
|
|
| XP1_SUPPORT_BROADCAST
|
|
| XP1_SUPPORT_MULTIPOINT
|
|
| XP1_IFS_HANDLES;
|
|
|
|
awpiRsvp[0].dwServiceFlags2 = 0;
|
|
awpiRsvp[0].dwServiceFlags3 = 0;
|
|
awpiRsvp[0].dwServiceFlags4 = 0;
|
|
awpiRsvp[0].dwProviderFlags = PFL_MATCHES_PROTOCOL_ZERO;
|
|
|
|
// Copy the GUID
|
|
memcpy(&(awpiRsvp[0].ProviderId), &c_guidRsvpNtName,
|
|
sizeof(awpiRsvp[0].ProviderId));
|
|
|
|
awpiRsvp[0].dwCatalogEntryId = 0;
|
|
awpiRsvp[0].ProtocolChain.ChainLen = 1;
|
|
// Change history
|
|
// 2 in Win98 and in NT 5 during development
|
|
// 4 in Windows 2000, to be different from Win98 as the API changed slightly (RAID #299558)
|
|
// 6 In Whistler as RSVPSP calls default provider rather than MSAFD, to handle Proxy client
|
|
awpiRsvp[0].iVersion = 6;
|
|
awpiRsvp[0].iAddressFamily = AF_INET;
|
|
awpiRsvp[0].iMaxSockAddr = 16;
|
|
awpiRsvp[0].iMinSockAddr = 16;
|
|
awpiRsvp[0].iSocketType = SOCK_DGRAM;
|
|
awpiRsvp[0].iProtocol = IPPROTO_UDP;
|
|
awpiRsvp[0].iProtocolMaxOffset = 0;
|
|
awpiRsvp[0].iNetworkByteOrder = BIGENDIAN;
|
|
awpiRsvp[0].iSecurityScheme = SECURITY_PROTOCOL_NONE;
|
|
|
|
//$ REVIEW : CWill : 08/07/97 : This is what UDP returns...
|
|
awpiRsvp[0].dwMessageSize = 0x0000ffbb;
|
|
awpiRsvp[0].dwProviderReserved = 0;
|
|
|
|
// Copy over the name
|
|
lstrcpynW(awpiRsvp[0].szProtocol, c_szChainNameUdp,
|
|
(WSAPROTOCOL_LEN + 1));
|
|
|
|
|
|
//
|
|
// Setup the TCP provider
|
|
//
|
|
|
|
awpiRsvp[1].dwServiceFlags1 =
|
|
XP1_GUARANTEED_DELIVERY
|
|
| XP1_GUARANTEED_ORDER
|
|
| XP1_GRACEFUL_CLOSE
|
|
| XP1_EXPEDITED_DATA
|
|
| XP1_QOS_SUPPORTED
|
|
| XP1_IFS_HANDLES;
|
|
|
|
awpiRsvp[1].dwServiceFlags2 = 0;
|
|
awpiRsvp[1].dwServiceFlags3 = 0;
|
|
awpiRsvp[1].dwServiceFlags4 = 0;
|
|
awpiRsvp[1].dwProviderFlags = PFL_MATCHES_PROTOCOL_ZERO;
|
|
|
|
// Copy the GUID
|
|
memcpy(&(awpiRsvp[1].ProviderId), &c_guidRsvpNtName,
|
|
sizeof(awpiRsvp[1].ProviderId));
|
|
|
|
awpiRsvp[1].dwCatalogEntryId = 0;
|
|
awpiRsvp[1].ProtocolChain.ChainLen = 1;
|
|
// Change history
|
|
// 2 in Win98 and in NT 5 during development
|
|
// 4 in Windows 2000, to be different from Win98 as the API changed slightly (RAID #299558)
|
|
// 6 In Whistler, as RSVPSP calls default provider rather than MSAFD, to handle Proxy client
|
|
awpiRsvp[1].iVersion = 6;
|
|
awpiRsvp[1].iAddressFamily = AF_INET;
|
|
awpiRsvp[1].iMaxSockAddr = 16;
|
|
awpiRsvp[1].iMinSockAddr = 16;
|
|
awpiRsvp[1].iSocketType = SOCK_STREAM;
|
|
awpiRsvp[1].iProtocol = IPPROTO_TCP;
|
|
awpiRsvp[1].iProtocolMaxOffset = 0;
|
|
awpiRsvp[1].iNetworkByteOrder = BIGENDIAN;
|
|
awpiRsvp[1].iSecurityScheme = SECURITY_PROTOCOL_NONE;
|
|
awpiRsvp[1].dwMessageSize = 0;
|
|
awpiRsvp[1].dwProviderReserved = 0;
|
|
|
|
// Copy over the name
|
|
lstrcpynW(awpiRsvp[1].szProtocol, c_szChainNameTcp,
|
|
(WSAPROTOCOL_LEN + 1));
|
|
|
|
|
|
// Install the provider
|
|
#ifdef _WIN64
|
|
// On 64 bit machines modify both 64 and 32 bit catalogs.
|
|
result = ::WSCInstallProvider64_32(
|
|
#else
|
|
result = ::WSCInstallProvider(
|
|
#endif
|
|
(GUID*) &c_guidRsvpNtName,
|
|
c_szRsvpFullPath,
|
|
awpiRsvp,
|
|
celems(awpiRsvp),
|
|
&err);
|
|
|
|
if (SOCKET_ERROR == result)
|
|
{
|
|
hr = HRESULT_FROM_WIN32(err);
|
|
}
|
|
|
|
TraceError("HrInstallRsvpProvider", hr);
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: RemoveRsvpProvider
|
|
//
|
|
// Purpose: Remove RSVP from the list of registered WinSock providers
|
|
//
|
|
// Arguments: None
|
|
//
|
|
// Returns: Nil
|
|
//
|
|
VOID RemoveRsvpProvider(VOID)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
INT err = NO_ERROR;
|
|
ULONG result = NO_ERROR;
|
|
DWORD dwBuffSize = 0;
|
|
WSAPROTOCOL_INFO* pwpiProtoInfo = NULL;
|
|
WSAPROTOCOL_INFO* pwpiInfo = NULL;
|
|
|
|
// Find all the protocols that are installed
|
|
//
|
|
result = ::WSCEnumProtocols(
|
|
NULL,
|
|
NULL,
|
|
&dwBuffSize,
|
|
&err);
|
|
if ((SOCKET_ERROR == result) && (WSAENOBUFS != err))
|
|
{
|
|
// We have a real error
|
|
//
|
|
hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
|
|
}
|
|
else
|
|
{
|
|
pwpiProtoInfo = reinterpret_cast<WSAPROTOCOL_INFO*>(new BYTE[dwBuffSize]);
|
|
if (pwpiProtoInfo)
|
|
{
|
|
// Find out all the protocols on the system
|
|
//
|
|
result = ::WSCEnumProtocols(
|
|
NULL,
|
|
pwpiProtoInfo,
|
|
&dwBuffSize,
|
|
&err);
|
|
|
|
pwpiInfo = pwpiProtoInfo;
|
|
if (SOCKET_ERROR != result)
|
|
{
|
|
DWORD cProt;
|
|
|
|
cProt = result;
|
|
hr = HRESULT_FROM_WIN32(ERROR_SERVICE_NOT_FOUND);
|
|
|
|
// Look for the RSVP protocol
|
|
//
|
|
while (cProt--)
|
|
{
|
|
if (pwpiInfo->ProviderId == c_guidRsvpNtName)
|
|
{
|
|
AssertSz((XP1_QOS_SUPPORTED
|
|
& pwpiInfo->dwServiceFlags1),
|
|
"Why is QoS not supported?");
|
|
AssertSz(((IPPROTO_UDP == pwpiInfo->iProtocol)
|
|
|| (IPPROTO_TCP == pwpiInfo->iProtocol)),
|
|
"Unknown RSVP protocol");
|
|
|
|
// Remove the RSVP provider
|
|
//
|
|
result = ::WSCDeinstallProvider(
|
|
&(pwpiInfo->ProviderId), &err);
|
|
if (SOCKET_ERROR == result)
|
|
{
|
|
hr = HRESULT_FROM_WIN32(err);
|
|
TraceTag(ttidError,
|
|
"Failed to De-Install Protocol, error = %d, Proto = %X\n",
|
|
err,
|
|
pwpiInfo->iProtocol);
|
|
}
|
|
|
|
#ifdef _WIN64
|
|
//
|
|
// Deinstall 32 bit provider as well.
|
|
// We always install both versions, so should uninstall both
|
|
// as well (both providers have the same ID, so we do not
|
|
// need to enumerate 32 bit catalog).
|
|
result = ::WSCDeinstallProvider32(
|
|
&(pwpiInfo->ProviderId), &err);
|
|
if (SOCKET_ERROR == result)
|
|
{
|
|
hr = HRESULT_FROM_WIN32(err);
|
|
TraceTag(ttidError,
|
|
"Failed to De-Install Protocol (32 bit), error = %d, Proto = %X\n",
|
|
err,
|
|
pwpiInfo->iProtocol);
|
|
}
|
|
#endif
|
|
// We have found it
|
|
//
|
|
hr = S_OK;
|
|
break;
|
|
}
|
|
|
|
pwpiInfo++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
TraceTag(
|
|
ttidError,
|
|
"Failed to Enumerate protocols, error = %d\n",
|
|
err);
|
|
hr = HRESULT_FROM_WIN32(err);
|
|
}
|
|
|
|
// Free the allocation
|
|
//
|
|
delete pwpiProtoInfo;
|
|
}
|
|
}
|
|
|
|
TraceErrorOptional("RemoveRsvpProvider", hr,
|
|
(ERROR_SERVICE_NOT_FOUND == hr));
|
|
return;
|
|
}
|
|
|
|
/*
|
|
// ----------------------------------------------------------------------
|
|
//
|
|
// Function: HrFindRsvpProvider
|
|
//
|
|
// Purpose:
|
|
// This routine installs the service provider.
|
|
//
|
|
// Arguments:
|
|
// iProtocolId [in] protocol to find
|
|
// pwpiOutProtoInfo [in] pointer to returned proto info
|
|
//
|
|
// Returns: S_OK on success, otherwise an error code
|
|
//
|
|
// Author: kumarp 19-March-98
|
|
//
|
|
// Notes: This function was written mainly by cwill.
|
|
//
|
|
HRESULT HrFindRsvpProvider(INT iProtocolId, WSAPROTOCOL_INFO* pwpiOutProtoInfo)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
INT err = NO_ERROR;
|
|
ULONG result = NO_ERROR;
|
|
DWORD dwBuffSize = 0;
|
|
WSAPROTOCOL_INFO* pwpiProtoInfo = NULL;
|
|
WSAPROTOCOL_INFO* pwpiInfo = NULL;
|
|
|
|
result = WSCEnumProtocols(
|
|
NULL,
|
|
NULL,
|
|
&dwBuffSize,
|
|
&err);
|
|
|
|
if ((SOCKET_ERROR == result) && (WSAENOBUFS != err))
|
|
{
|
|
// We have a real error
|
|
hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
|
|
}
|
|
else
|
|
{
|
|
pwpiProtoInfo = reinterpret_cast<WSAPROTOCOL_INFO*>(new BYTE[dwBuffSize]);
|
|
if (pwpiProtoInfo)
|
|
{
|
|
// Find out all the protocols on the system
|
|
result = WSCEnumProtocols(
|
|
NULL,
|
|
pwpiProtoInfo,
|
|
&dwBuffSize,
|
|
&err);
|
|
|
|
pwpiInfo = pwpiProtoInfo;
|
|
if (SOCKET_ERROR != result)
|
|
{
|
|
DWORD cProt;
|
|
|
|
cProt = result;
|
|
hr = HRESULT_FROM_WIN32(ERROR_SERVICE_NOT_FOUND);
|
|
|
|
// Look for a protocol that supports QoS
|
|
while (cProt--)
|
|
{
|
|
if ((pwpiInfo->iProtocol == iProtocolId)
|
|
&& (XP1_QOS_SUPPORTED & pwpiInfo->dwServiceFlags1))
|
|
{
|
|
|
|
*pwpiOutProtoInfo = *pwpiInfo;
|
|
hr = S_OK;
|
|
break;
|
|
}
|
|
pwpiInfo++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
TraceTag(
|
|
ttidError,
|
|
"Failed to Enumerate protocols, error = %d\n",
|
|
err);
|
|
hr = HRESULT_FROM_WIN32(err);
|
|
}
|
|
|
|
delete pwpiProtoInfo;
|
|
}
|
|
}
|
|
|
|
TraceErrorOptional("HrFindRsvpProvider", hr,
|
|
(ERROR_SERVICE_NOT_FOUND == hr));
|
|
return hr;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------
|
|
//
|
|
// Function: RemoveRsvpProvider
|
|
//
|
|
// Purpose: Remove RSVP provider
|
|
//
|
|
// Arguments:
|
|
// iProtocolId [in] protocol id to remove
|
|
//
|
|
// Returns:
|
|
//
|
|
// Author: kumarp 19-March-98
|
|
//
|
|
// Notes: This function was written mainly by cwill.
|
|
//
|
|
VOID RemoveRsvpProvider(INT iProtocolId)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
WSAPROTOCOL_INFO wpiProtoInfo;
|
|
|
|
// Find the provider and remove it
|
|
hr = HrFindRsvpProvider(iProtocolId, &wpiProtoInfo);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
INT err = NO_ERROR;
|
|
#ifdef DBG
|
|
INT result =
|
|
#endif // DBG
|
|
|
|
WSCDeinstallProvider(&wpiProtoInfo.ProviderId, &err);
|
|
|
|
#ifdef DBG
|
|
if (SOCKET_ERROR == result)
|
|
{
|
|
hr = HRESULT_FROM_WIN32(err);
|
|
TraceTag(ttidError,
|
|
"Failed to De-Install Protocol, error = %d, Proto = %X\n",
|
|
err,
|
|
iProtocolId);
|
|
}
|
|
#endif // DBG
|
|
}
|
|
|
|
TraceErrorOptional("HrFindRsvpProvider", hr,
|
|
(ERROR_SERVICE_NOT_FOUND == hr));
|
|
return;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------
|
|
//
|
|
// Function: RemoveRsvpProviders
|
|
//
|
|
// Purpose: Remove RSVP providers
|
|
//
|
|
// Arguments: None
|
|
//
|
|
// Returns: None
|
|
//
|
|
// Author: kumarp 19-March-98
|
|
//
|
|
// Notes:
|
|
//
|
|
void RemoveRsvpProviders(VOID)
|
|
{
|
|
// Remove the providers if they are present
|
|
RemoveRsvpProvider(IPPROTO_UDP);
|
|
RemoveRsvpProvider(IPPROTO_TCP);
|
|
}
|
|
|
|
|
|
*/
|