Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

460 lines
14 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997.
  5. //
  6. // File: T C P R S V P . C P P
  7. //
  8. // Contents: RSVP portion of TCP/IP
  9. //
  10. // Notes:
  11. //
  12. // Author: kumarp 19-March-98
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "pch.h"
  16. #pragma hdrstop
  17. #include "ncnetcfg.h"
  18. #include <ws2spi.h>
  19. #include "ncsvc.h"
  20. const GUID c_guidRsvpNtName = { /* 9d60a9e0-337a-11d0-bd88-0000c082e69a */
  21. 0x9d60a9e0,
  22. 0x337a,
  23. 0x11d0,
  24. {0xbd, 0x88, 0x00, 0x00, 0xc0, 0x82, 0xe6, 0x9a}
  25. };
  26. static const WCHAR* c_szChainNameUdp = L"RSVP UDP Service Provider";
  27. static const WCHAR* c_szChainNameTcp = L"RSVP TCP Service Provider";
  28. static const WCHAR* c_szRsvpFullPath = L"%SystemRoot%\\system32\\rsvpsp.dll";
  29. // ----------------------------------------------------------------------
  30. //
  31. // Function: HrInstallRsvpProvider
  32. //
  33. // Purpose: This registers with winsock the RSVP TCP and UDP provider.
  34. // This allows QoS for TCP and UDP
  35. //
  36. // Arguments: None
  37. //
  38. // Returns: S_OK on success, otherwise an error code
  39. //
  40. // Author: kumarp 19-March-98
  41. //
  42. // Notes: This function was written mainly by cwill.
  43. //
  44. HRESULT HrInstallRsvpProvider(VOID)
  45. {
  46. HRESULT hr = S_OK;
  47. INT err = 0;
  48. INT result = 0;
  49. WSAPROTOCOL_INFO awpiRsvp[2];
  50. // Note: CWill : 08/08/97 : This is a hack to get TCP/IP
  51. // registered before RSVP. We have to get some way
  52. // of ordering RSVP after TCP/IP
  53. (VOID) HrRunWinsock2Migration();
  54. //
  55. // Setup the UDP provider
  56. //
  57. awpiRsvp[0].dwServiceFlags1 =
  58. XP1_QOS_SUPPORTED
  59. | XP1_CONNECTIONLESS
  60. | XP1_MESSAGE_ORIENTED
  61. | XP1_SUPPORT_BROADCAST
  62. | XP1_SUPPORT_MULTIPOINT
  63. | XP1_IFS_HANDLES;
  64. awpiRsvp[0].dwServiceFlags2 = 0;
  65. awpiRsvp[0].dwServiceFlags3 = 0;
  66. awpiRsvp[0].dwServiceFlags4 = 0;
  67. awpiRsvp[0].dwProviderFlags = PFL_MATCHES_PROTOCOL_ZERO;
  68. // Copy the GUID
  69. memcpy(&(awpiRsvp[0].ProviderId), &c_guidRsvpNtName,
  70. sizeof(awpiRsvp[0].ProviderId));
  71. awpiRsvp[0].dwCatalogEntryId = 0;
  72. awpiRsvp[0].ProtocolChain.ChainLen = 1;
  73. // Change history
  74. // 2 in Win98 and in NT 5 during development
  75. // 4 in Windows 2000, to be different from Win98 as the API changed slightly (RAID #299558)
  76. // 6 In Whistler as RSVPSP calls default provider rather than MSAFD, to handle Proxy client
  77. awpiRsvp[0].iVersion = 6;
  78. awpiRsvp[0].iAddressFamily = AF_INET;
  79. awpiRsvp[0].iMaxSockAddr = 16;
  80. awpiRsvp[0].iMinSockAddr = 16;
  81. awpiRsvp[0].iSocketType = SOCK_DGRAM;
  82. awpiRsvp[0].iProtocol = IPPROTO_UDP;
  83. awpiRsvp[0].iProtocolMaxOffset = 0;
  84. awpiRsvp[0].iNetworkByteOrder = BIGENDIAN;
  85. awpiRsvp[0].iSecurityScheme = SECURITY_PROTOCOL_NONE;
  86. //$ REVIEW : CWill : 08/07/97 : This is what UDP returns...
  87. awpiRsvp[0].dwMessageSize = 0x0000ffbb;
  88. awpiRsvp[0].dwProviderReserved = 0;
  89. // Copy over the name
  90. lstrcpynW(awpiRsvp[0].szProtocol, c_szChainNameUdp,
  91. (WSAPROTOCOL_LEN + 1));
  92. //
  93. // Setup the TCP provider
  94. //
  95. awpiRsvp[1].dwServiceFlags1 =
  96. XP1_GUARANTEED_DELIVERY
  97. | XP1_GUARANTEED_ORDER
  98. | XP1_GRACEFUL_CLOSE
  99. | XP1_EXPEDITED_DATA
  100. | XP1_QOS_SUPPORTED
  101. | XP1_IFS_HANDLES;
  102. awpiRsvp[1].dwServiceFlags2 = 0;
  103. awpiRsvp[1].dwServiceFlags3 = 0;
  104. awpiRsvp[1].dwServiceFlags4 = 0;
  105. awpiRsvp[1].dwProviderFlags = PFL_MATCHES_PROTOCOL_ZERO;
  106. // Copy the GUID
  107. memcpy(&(awpiRsvp[1].ProviderId), &c_guidRsvpNtName,
  108. sizeof(awpiRsvp[1].ProviderId));
  109. awpiRsvp[1].dwCatalogEntryId = 0;
  110. awpiRsvp[1].ProtocolChain.ChainLen = 1;
  111. // Change history
  112. // 2 in Win98 and in NT 5 during development
  113. // 4 in Windows 2000, to be different from Win98 as the API changed slightly (RAID #299558)
  114. // 6 In Whistler, as RSVPSP calls default provider rather than MSAFD, to handle Proxy client
  115. awpiRsvp[1].iVersion = 6;
  116. awpiRsvp[1].iAddressFamily = AF_INET;
  117. awpiRsvp[1].iMaxSockAddr = 16;
  118. awpiRsvp[1].iMinSockAddr = 16;
  119. awpiRsvp[1].iSocketType = SOCK_STREAM;
  120. awpiRsvp[1].iProtocol = IPPROTO_TCP;
  121. awpiRsvp[1].iProtocolMaxOffset = 0;
  122. awpiRsvp[1].iNetworkByteOrder = BIGENDIAN;
  123. awpiRsvp[1].iSecurityScheme = SECURITY_PROTOCOL_NONE;
  124. awpiRsvp[1].dwMessageSize = 0;
  125. awpiRsvp[1].dwProviderReserved = 0;
  126. // Copy over the name
  127. lstrcpynW(awpiRsvp[1].szProtocol, c_szChainNameTcp,
  128. (WSAPROTOCOL_LEN + 1));
  129. // Install the provider
  130. #ifdef _WIN64
  131. // On 64 bit machines modify both 64 and 32 bit catalogs.
  132. result = ::WSCInstallProvider64_32(
  133. #else
  134. result = ::WSCInstallProvider(
  135. #endif
  136. (GUID*) &c_guidRsvpNtName,
  137. c_szRsvpFullPath,
  138. awpiRsvp,
  139. celems(awpiRsvp),
  140. &err);
  141. if (SOCKET_ERROR == result)
  142. {
  143. hr = HRESULT_FROM_WIN32(err);
  144. }
  145. TraceError("HrInstallRsvpProvider", hr);
  146. return hr;
  147. }
  148. //+---------------------------------------------------------------------------
  149. //
  150. // Member: RemoveRsvpProvider
  151. //
  152. // Purpose: Remove RSVP from the list of registered WinSock providers
  153. //
  154. // Arguments: None
  155. //
  156. // Returns: Nil
  157. //
  158. VOID RemoveRsvpProvider(VOID)
  159. {
  160. HRESULT hr = S_OK;
  161. INT err = NO_ERROR;
  162. ULONG result = NO_ERROR;
  163. DWORD dwBuffSize = 0;
  164. WSAPROTOCOL_INFO* pwpiProtoInfo = NULL;
  165. WSAPROTOCOL_INFO* pwpiInfo = NULL;
  166. // Find all the protocols that are installed
  167. //
  168. result = ::WSCEnumProtocols(
  169. NULL,
  170. NULL,
  171. &dwBuffSize,
  172. &err);
  173. if ((SOCKET_ERROR == result) && (WSAENOBUFS != err))
  174. {
  175. // We have a real error
  176. //
  177. hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
  178. }
  179. else
  180. {
  181. pwpiProtoInfo = reinterpret_cast<WSAPROTOCOL_INFO*>(new BYTE[dwBuffSize]);
  182. if (pwpiProtoInfo)
  183. {
  184. // Find out all the protocols on the system
  185. //
  186. result = ::WSCEnumProtocols(
  187. NULL,
  188. pwpiProtoInfo,
  189. &dwBuffSize,
  190. &err);
  191. pwpiInfo = pwpiProtoInfo;
  192. if (SOCKET_ERROR != result)
  193. {
  194. DWORD cProt;
  195. cProt = result;
  196. hr = HRESULT_FROM_WIN32(ERROR_SERVICE_NOT_FOUND);
  197. // Look for the RSVP protocol
  198. //
  199. while (cProt--)
  200. {
  201. if (pwpiInfo->ProviderId == c_guidRsvpNtName)
  202. {
  203. AssertSz((XP1_QOS_SUPPORTED
  204. & pwpiInfo->dwServiceFlags1),
  205. "Why is QoS not supported?");
  206. AssertSz(((IPPROTO_UDP == pwpiInfo->iProtocol)
  207. || (IPPROTO_TCP == pwpiInfo->iProtocol)),
  208. "Unknown RSVP protocol");
  209. // Remove the RSVP provider
  210. //
  211. result = ::WSCDeinstallProvider(
  212. &(pwpiInfo->ProviderId), &err);
  213. if (SOCKET_ERROR == result)
  214. {
  215. hr = HRESULT_FROM_WIN32(err);
  216. TraceTag(ttidError,
  217. "Failed to De-Install Protocol, error = %d, Proto = %X\n",
  218. err,
  219. pwpiInfo->iProtocol);
  220. }
  221. #ifdef _WIN64
  222. //
  223. // Deinstall 32 bit provider as well.
  224. // We always install both versions, so should uninstall both
  225. // as well (both providers have the same ID, so we do not
  226. // need to enumerate 32 bit catalog).
  227. result = ::WSCDeinstallProvider32(
  228. &(pwpiInfo->ProviderId), &err);
  229. if (SOCKET_ERROR == result)
  230. {
  231. hr = HRESULT_FROM_WIN32(err);
  232. TraceTag(ttidError,
  233. "Failed to De-Install Protocol (32 bit), error = %d, Proto = %X\n",
  234. err,
  235. pwpiInfo->iProtocol);
  236. }
  237. #endif
  238. // We have found it
  239. //
  240. hr = S_OK;
  241. break;
  242. }
  243. pwpiInfo++;
  244. }
  245. }
  246. else
  247. {
  248. TraceTag(
  249. ttidError,
  250. "Failed to Enumerate protocols, error = %d\n",
  251. err);
  252. hr = HRESULT_FROM_WIN32(err);
  253. }
  254. // Free the allocation
  255. //
  256. delete pwpiProtoInfo;
  257. }
  258. }
  259. TraceErrorOptional("RemoveRsvpProvider", hr,
  260. (ERROR_SERVICE_NOT_FOUND == hr));
  261. return;
  262. }
  263. /*
  264. // ----------------------------------------------------------------------
  265. //
  266. // Function: HrFindRsvpProvider
  267. //
  268. // Purpose:
  269. // This routine installs the service provider.
  270. //
  271. // Arguments:
  272. // iProtocolId [in] protocol to find
  273. // pwpiOutProtoInfo [in] pointer to returned proto info
  274. //
  275. // Returns: S_OK on success, otherwise an error code
  276. //
  277. // Author: kumarp 19-March-98
  278. //
  279. // Notes: This function was written mainly by cwill.
  280. //
  281. HRESULT HrFindRsvpProvider(INT iProtocolId, WSAPROTOCOL_INFO* pwpiOutProtoInfo)
  282. {
  283. HRESULT hr = S_OK;
  284. INT err = NO_ERROR;
  285. ULONG result = NO_ERROR;
  286. DWORD dwBuffSize = 0;
  287. WSAPROTOCOL_INFO* pwpiProtoInfo = NULL;
  288. WSAPROTOCOL_INFO* pwpiInfo = NULL;
  289. result = WSCEnumProtocols(
  290. NULL,
  291. NULL,
  292. &dwBuffSize,
  293. &err);
  294. if ((SOCKET_ERROR == result) && (WSAENOBUFS != err))
  295. {
  296. // We have a real error
  297. hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
  298. }
  299. else
  300. {
  301. pwpiProtoInfo = reinterpret_cast<WSAPROTOCOL_INFO*>(new BYTE[dwBuffSize]);
  302. if (pwpiProtoInfo)
  303. {
  304. // Find out all the protocols on the system
  305. result = WSCEnumProtocols(
  306. NULL,
  307. pwpiProtoInfo,
  308. &dwBuffSize,
  309. &err);
  310. pwpiInfo = pwpiProtoInfo;
  311. if (SOCKET_ERROR != result)
  312. {
  313. DWORD cProt;
  314. cProt = result;
  315. hr = HRESULT_FROM_WIN32(ERROR_SERVICE_NOT_FOUND);
  316. // Look for a protocol that supports QoS
  317. while (cProt--)
  318. {
  319. if ((pwpiInfo->iProtocol == iProtocolId)
  320. && (XP1_QOS_SUPPORTED & pwpiInfo->dwServiceFlags1))
  321. {
  322. *pwpiOutProtoInfo = *pwpiInfo;
  323. hr = S_OK;
  324. break;
  325. }
  326. pwpiInfo++;
  327. }
  328. }
  329. else
  330. {
  331. TraceTag(
  332. ttidError,
  333. "Failed to Enumerate protocols, error = %d\n",
  334. err);
  335. hr = HRESULT_FROM_WIN32(err);
  336. }
  337. delete pwpiProtoInfo;
  338. }
  339. }
  340. TraceErrorOptional("HrFindRsvpProvider", hr,
  341. (ERROR_SERVICE_NOT_FOUND == hr));
  342. return hr;
  343. }
  344. // ----------------------------------------------------------------------
  345. //
  346. // Function: RemoveRsvpProvider
  347. //
  348. // Purpose: Remove RSVP provider
  349. //
  350. // Arguments:
  351. // iProtocolId [in] protocol id to remove
  352. //
  353. // Returns:
  354. //
  355. // Author: kumarp 19-March-98
  356. //
  357. // Notes: This function was written mainly by cwill.
  358. //
  359. VOID RemoveRsvpProvider(INT iProtocolId)
  360. {
  361. HRESULT hr = S_OK;
  362. WSAPROTOCOL_INFO wpiProtoInfo;
  363. // Find the provider and remove it
  364. hr = HrFindRsvpProvider(iProtocolId, &wpiProtoInfo);
  365. if (SUCCEEDED(hr))
  366. {
  367. INT err = NO_ERROR;
  368. #ifdef DBG
  369. INT result =
  370. #endif // DBG
  371. WSCDeinstallProvider(&wpiProtoInfo.ProviderId, &err);
  372. #ifdef DBG
  373. if (SOCKET_ERROR == result)
  374. {
  375. hr = HRESULT_FROM_WIN32(err);
  376. TraceTag(ttidError,
  377. "Failed to De-Install Protocol, error = %d, Proto = %X\n",
  378. err,
  379. iProtocolId);
  380. }
  381. #endif // DBG
  382. }
  383. TraceErrorOptional("HrFindRsvpProvider", hr,
  384. (ERROR_SERVICE_NOT_FOUND == hr));
  385. return;
  386. }
  387. // ----------------------------------------------------------------------
  388. //
  389. // Function: RemoveRsvpProviders
  390. //
  391. // Purpose: Remove RSVP providers
  392. //
  393. // Arguments: None
  394. //
  395. // Returns: None
  396. //
  397. // Author: kumarp 19-March-98
  398. //
  399. // Notes:
  400. //
  401. void RemoveRsvpProviders(VOID)
  402. {
  403. // Remove the providers if they are present
  404. RemoveRsvpProvider(IPPROTO_UDP);
  405. RemoveRsvpProvider(IPPROTO_TCP);
  406. }
  407. */