//+--------------------------------------------------------------------------- // // 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 #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(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(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); } */