Leaked source code of windows server 2003
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.

191 lines
4.0 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) Microsoft Corporation
  4. //
  5. // SYNOPSIS
  6. //
  7. // Defines the class CPortParser.
  8. //
  9. ///////////////////////////////////////////////////////////////////////////////
  10. #include "ias.h"
  11. #include "iasutil.h"
  12. #include "winsock2.h"
  13. #include "portparser.h"
  14. #include <cwchar>
  15. HRESULT CPortParser::GetIPAddress(DWORD* ipAddress) throw ()
  16. {
  17. if (ipAddress == 0)
  18. {
  19. return E_POINTER;
  20. }
  21. // If we're at the end of the string, there's no more interfaces.
  22. if (*next == L'\0')
  23. {
  24. return S_FALSE;
  25. }
  26. // Find the end of the IP address.
  27. const wchar_t* end = wcschr(next, addressPortDelim);
  28. if (end != 0)
  29. {
  30. // Compute the length of the address token.
  31. size_t nChar = end - next;
  32. if (nChar > maxAddrStrLen)
  33. {
  34. return E_INVALIDARG;
  35. }
  36. // Make a null-terminated copy of the address token.
  37. wchar_t addrStr[maxAddrStrLen + 1];
  38. wmemcpy(addrStr, next, nChar);
  39. addrStr[nChar] = L'\0';
  40. // Convert to a network order integer.
  41. *ipAddress = htonl(ias_inet_wtoh(addrStr));
  42. // Was the conversion successful.
  43. if (*ipAddress == INADDR_NONE)
  44. {
  45. return E_INVALIDARG;
  46. }
  47. // Position the cursor right after the delimiter.
  48. next = end + 1;
  49. }
  50. else
  51. {
  52. // No end, thus no IP address. Defaults to INADDR_ANY.
  53. *ipAddress = INADDR_ANY;
  54. }
  55. // The cursor should be positioned on the first port.
  56. if (!iswdigit(*next))
  57. {
  58. return E_INVALIDARG;
  59. }
  60. return S_OK;
  61. }
  62. HRESULT CPortParser::GetNextPort(WORD* port) throw ()
  63. {
  64. if (port == 0)
  65. {
  66. return E_POINTER;
  67. }
  68. // If we're at the end of the string, there's no more ports.
  69. if (*next == L'\0')
  70. {
  71. return S_FALSE;
  72. }
  73. // Are we at the end of the interface?
  74. if (*next == interfaceDelim)
  75. {
  76. // Skip past the interface delimiter.
  77. ++next;
  78. // The cursor should be positioned on an address or a port; either way it
  79. // has to be a digit.
  80. return iswdigit(*next) ? S_FALSE : E_INVALIDARG;
  81. }
  82. // Convert the port number.
  83. const wchar_t* end;
  84. unsigned long value = wcstoul(next, const_cast<wchar_t**>(&end), 10);
  85. // Make sure we converted something and it's in range.
  86. if ((end == next) || (value < minPortValue) || (value > maxPortValue))
  87. {
  88. return E_INVALIDARG;
  89. }
  90. // Set the cursor to just after the port number.
  91. next = end;
  92. // Is there another port?
  93. if (*next == portDelim)
  94. {
  95. // Yes, so advance to the next one.
  96. ++next;
  97. // Must be a digit.
  98. if (!iswdigit(*next))
  99. {
  100. return E_INVALIDARG;
  101. }
  102. }
  103. // No more ports, so we should either be at the end of the interface or the
  104. // end of the string.
  105. else if ((*next != interfaceDelim) && (*next != L'\0'))
  106. {
  107. return E_INVALIDARG;
  108. }
  109. *port = static_cast<WORD>(value);
  110. return S_OK;
  111. }
  112. size_t CPortParser::CountPorts(const wchar_t* portString) throw ()
  113. {
  114. if (portString == 0)
  115. {
  116. return 0;
  117. }
  118. CPortParser parser(portString);
  119. // There must be at least one IP address.
  120. DWORD ipAddr;
  121. HRESULT hr = parser.GetIPAddress(&ipAddr);
  122. if (hr != S_OK)
  123. {
  124. return 0;
  125. }
  126. size_t count = 0;
  127. do
  128. {
  129. // There must be at least one port per IP address.
  130. WORD port;
  131. hr = parser.GetNextPort(&port);
  132. if (hr != S_OK)
  133. {
  134. return 0;
  135. }
  136. ++count;
  137. // Get the remaining ports (if any).
  138. do
  139. {
  140. hr = parser.GetNextPort(&port);
  141. if (FAILED(hr))
  142. {
  143. return 0;
  144. }
  145. ++count;
  146. }
  147. while (hr == S_OK);
  148. // Get the next IP address (if any).
  149. hr = parser.GetIPAddress(&ipAddr);
  150. if (FAILED(hr))
  151. {
  152. return 0;
  153. }
  154. } while (hr == S_OK);
  155. return count;
  156. }