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.

1442 lines
37 KiB

  1. /*
  2. * Filename: NLB_XMLParser.cpp
  3. * Description:
  4. * Author: shouse, 04.10.01
  5. */
  6. #include "stdafx.h"
  7. #include "NLB_XMLParser.h"
  8. #define NLB_XML_ELEMENT_CLUSTER L"Cluster"
  9. #define NLB_XML_ELEMENT_PROPERTIES L"Properties"
  10. #define NLB_XML_ELEMENT_HOSTS L"Hosts"
  11. #define NLB_XML_ELEMENT_HOST L"Host"
  12. #define NLB_XML_ELEMENT_PORTRULES L"PortRules"
  13. #define NLB_XML_ELEMENT_IPADDRESS L"IPAddress"
  14. #define NLB_XML_ELEMENT_ADDRESS L"Address"
  15. #define NLB_XML_ELEMENT_SUBNETMASK L"SubnetMask"
  16. #define NLB_XML_ELEMENT_ADAPTER L"Adapter"
  17. #define NLB_XML_ELEMENT_GUID L"GUID"
  18. #define NLB_XML_ELEMENT_NAME L"Name"
  19. #define NLB_XML_ELEMENT_DOMAINNAME L"DomainName"
  20. #define NLB_XML_ELEMENT_HOSTNAME L"HostName"
  21. #define NLB_XML_ELEMENT_NETWORKADDRESS L"NetworkAddress"
  22. #define NLB_XML_ELEMENT_CLUSTER_MODE L"Mode"
  23. #define NLB_XML_ELEMENT_REMOTE_CONTROL L"RemoteControl"
  24. #define NLB_XML_ELEMENT_PASSWORD L"Password"
  25. #define NLB_XML_ATTRIBUTE_NAME L"Name"
  26. #define NLB_XML_ATTRIBUTE_TYPE L"Type"
  27. #define NLB_XML_ATTRIBUTE_TEXT L"Text"
  28. #define NLB_XML_ATTRIBUTE_ENABLED L"Enabled"
  29. #define NLB_XML_ATTRIBUTE_HOSTID L"HostID"
  30. #define NLB_XML_ATTRIBUTE_STATE L"State"
  31. #define NLB_XML_VALUE_PRIMARY L"Primary"
  32. #define NLB_XML_VALUE_SECONDARY L"Secondary"
  33. #define NLB_XML_VALUE_VIRTUAL L"Virtual"
  34. #define NLB_XML_VALUE_DEDICATED L"Dedicated"
  35. #define NLB_XML_VALUE_CONNECTION L"Connection"
  36. #define NLB_XML_VALUE_IGMP L"IGMP"
  37. #define NLB_XML_VALUE_UNICAST L"Unicast"
  38. #define NLB_XML_VALUE_MULTICAST L"Multicast"
  39. #define NLB_XML_VALUE_YES L"Yes"
  40. #define NLB_XML_VALUE_NO L"No"
  41. #define NLB_XML_VALUE_STARTED L"Started"
  42. #define NLB_XML_VALUE_STOPPED L"Stopped"
  43. #define NLB_XML_VALUE_SUSPENDED L"Suspended"
  44. #define NLB_XML_PARSE_ERROR_IPADDRESS_ADAPTER_CODE MAKE_HRESULT(SEVERITY_ERROR, FACILITY_NLB, NLB_XML_E_IPADDRESS_ADAPTER)
  45. #define NLB_XML_PARSE_ERROR_IPADDRESS_ADAPTER_REASON L"Only \"Dedicated\" and \"Connection\" IP address types may specify <Adapter> child elements."
  46. /*
  47. * Method:
  48. * Description:
  49. * Author:
  50. */
  51. NLB_XMLParser::NLB_XMLParser () {
  52. pDoc = NULL;
  53. pSchema = NULL;
  54. bShowErrorPopups = true;
  55. ClusterList.clear();
  56. ZeroMemory(&ParseError, sizeof(NLB_XMLError));
  57. }
  58. /*
  59. * Method:
  60. * Description:
  61. * Author:
  62. */
  63. NLB_XMLParser::NLB_XMLParser (bool bSilent) {
  64. pDoc = NULL;
  65. pSchema = NULL;
  66. bShowErrorPopups = !bSilent;
  67. ClusterList.clear();
  68. ZeroMemory(&ParseError, sizeof(NLB_XMLError));
  69. }
  70. /*
  71. * Method:
  72. * Description:
  73. * Author:
  74. */
  75. NLB_XMLParser::~NLB_XMLParser () {
  76. }
  77. /*
  78. * Method:
  79. * Description:
  80. * Author:
  81. */
  82. void NLB_XMLParser::GetParseError (NLB_XMLError * pError) {
  83. *pError = ParseError;
  84. }
  85. /*
  86. * Method:
  87. * Description:
  88. * Author:
  89. */
  90. void NLB_XMLParser::SetParseError (HRESULT hrCode, PWSTR pwszReason) {
  91. ParseError.code = hrCode;
  92. lstrcpy(ParseError.wszReason, pwszReason);
  93. }
  94. /*
  95. * Method:
  96. * Description:
  97. * Author:
  98. */
  99. HRESULT NLB_XMLParser::LoadDocument (BSTR pBURL) {
  100. VARIANT vURL;
  101. VARIANT_BOOL vb;
  102. VARIANT varValue;
  103. HRESULT hr = S_OK;
  104. IErrorInfo * perror;
  105. BSTR foo;
  106. CHECKHR(pDoc->put_async(VARIANT_FALSE));
  107. VariantInit(&vURL);
  108. vURL.vt = VT_BSTR;
  109. V_BSTR(&vURL) = pBURL;
  110. CHECKHR(CoCreateInstance(MSXML2::CLSID_XMLSchemaCache, NULL, CLSCTX_SERVER,
  111. MSXML2::IID_IXMLDOMSchemaCollection, (LPVOID*)(&pSchema)));
  112. if (pSchema) {
  113. pSchema->add(L"x-schema:MicrosoftNLB", _variant_t(L"MicrosoftNLB.xml"));
  114. varValue.vt = VT_DISPATCH;
  115. varValue.pdispVal = pSchema;
  116. CHECKHR(pDoc->putref_schemas(varValue));
  117. CHECKHR(pDoc->load(vURL, &vb));
  118. CHECKHR(CheckDocumentLoad());
  119. }
  120. CleanUp:
  121. SAFERELEASE(pSchema);
  122. return hr;
  123. }
  124. /*
  125. * Method:
  126. * Description:
  127. * Author:
  128. */
  129. HRESULT NLB_XMLParser::CheckDocumentLoad () {
  130. MSXML2::IXMLDOMParseError * pXMLError = NULL;
  131. HRESULT hr = S_OK;
  132. CHECKHR(pDoc->get_parseError(&pXMLError));
  133. CHECKHR(pXMLError->get_errorCode(&ParseError.code));
  134. if (ParseError.code != 0) {
  135. BSTR pBURL;
  136. BSTR pBReason;
  137. CHECKHR(pXMLError->get_line(&ParseError.line));
  138. CHECKHR(pXMLError->get_linepos(&ParseError.character));
  139. CHECKHR(pXMLError->get_URL(&pBURL));
  140. lstrcpy(ParseError.wszURL, pBURL);
  141. CHECKHR(pXMLError->get_reason(&pBReason));
  142. lstrcpy(ParseError.wszReason, pBReason);
  143. SysFreeString(pBURL);
  144. SysFreeString(pBReason);
  145. }
  146. if (bShowErrorPopups) {
  147. WCHAR reason[2048];
  148. WCHAR details[2048];
  149. if (ParseError.code != 0) {
  150. wsprintf(reason, L"Error 0x%08x:\n\n%ls\n", ParseError.code, ParseError.wszReason);
  151. if (ParseError.line > 0) {
  152. wsprintf(details, L"Error on line %d, position %d in \"%ls\".\n",
  153. ParseError.line, ParseError.character, ParseError.wszURL);
  154. lstrcat(reason, details);
  155. }
  156. ::MessageBox(NULL, reason, L"NLB XML Document Error",
  157. MB_APPLMODAL | MB_ICONSTOP | MB_OK);
  158. } else {
  159. wsprintf(reason, L"XML Document successfully loaded.");
  160. ::MessageBox(NULL, reason, L"NLB XML Document Information",
  161. MB_APPLMODAL | MB_ICONINFORMATION | MB_OK);
  162. }
  163. }
  164. CleanUp:
  165. SAFERELEASE(pXMLError);
  166. return ParseError.code;
  167. }
  168. /*
  169. * Method:
  170. * Description:
  171. * Author:
  172. */
  173. BSTR NLB_XMLParser::AsciiToBSTR (const char * pszName) {
  174. WCHAR wszString[MAX_PATH];
  175. ::MultiByteToWideChar(CP_ACP, 0, pszName, -1, wszString, MAX_PATH);
  176. return SysAllocString(wszString);
  177. }
  178. /*
  179. * Method:
  180. * Description:
  181. * Author:
  182. */
  183. CHAR * NLB_XMLParser::BSTRToAscii (const WCHAR * pwszName) {
  184. CHAR szString[MAX_PATH];
  185. ::WideCharToMultiByte(CP_ACP, 0, pwszName, -1, szString, MAX_PATH, NULL, NULL);
  186. return _strdup(szString);
  187. }
  188. /*
  189. * Method:
  190. * Description:
  191. * Author:
  192. */
  193. NLB_IPAddress::NLB_IPAddressType NLB_XMLParser::StringToIPAddressType (const WCHAR * pwszType) {
  194. if (!lstrcmpi(pwszType, NLB_XML_VALUE_PRIMARY)) {
  195. return NLB_IPAddress::Primary;
  196. } else if (!lstrcmpi(pwszType, NLB_XML_VALUE_SECONDARY)) {
  197. return NLB_IPAddress::Secondary;
  198. } else if (!lstrcmpi(pwszType, NLB_XML_VALUE_VIRTUAL)) {
  199. return NLB_IPAddress::Virtual;
  200. } else if (!lstrcmpi(pwszType, NLB_XML_VALUE_DEDICATED)) {
  201. return NLB_IPAddress::Dedicated;
  202. } else if (!lstrcmpi(pwszType, NLB_XML_VALUE_CONNECTION)) {
  203. return NLB_IPAddress::Connection;
  204. } else if (!lstrcmpi(pwszType, NLB_XML_VALUE_IGMP)) {
  205. return NLB_IPAddress::IGMP;
  206. }
  207. return NLB_IPAddress::Invalid;
  208. }
  209. /*
  210. * Method:
  211. * Description:
  212. * Author:
  213. */
  214. NLB_ClusterMode::NLB_ClusterModeType NLB_XMLParser::StringToClusterMode (const WCHAR * pwszType) {
  215. if (!lstrcmpi(pwszType, NLB_XML_VALUE_UNICAST)) {
  216. return NLB_ClusterMode::Unicast;
  217. } else if (!lstrcmpi(pwszType, NLB_XML_VALUE_MULTICAST)) {
  218. return NLB_ClusterMode::Multicast;
  219. } else if (!lstrcmpi(pwszType, NLB_XML_VALUE_IGMP)) {
  220. return NLB_ClusterMode::IGMP;
  221. }
  222. return NLB_ClusterMode::Invalid;
  223. }
  224. /*
  225. * Method:
  226. * Description:
  227. * Author:
  228. */
  229. NLB_HostState::NLB_HostStateType NLB_XMLParser::StringToHostState (const WCHAR * pwszState) {
  230. if (!lstrcmpi(pwszState, NLB_XML_VALUE_STARTED)) {
  231. return NLB_HostState::Started;
  232. } else if (!lstrcmpi(pwszState, NLB_XML_VALUE_STOPPED)) {
  233. return NLB_HostState::Stopped;
  234. } else if (!lstrcmpi(pwszState, NLB_XML_VALUE_SUSPENDED)) {
  235. return NLB_HostState::Suspended;
  236. }
  237. return NLB_HostState::Invalid;
  238. }
  239. /*
  240. * Method:
  241. * Description:
  242. * Author:
  243. */
  244. NLB_RemoteControl::NLB_RemoteControlEnabled NLB_XMLParser::StringToRemoteControlEnabled (const WCHAR * pwszType) {
  245. if (!lstrcmpi(pwszType, NLB_XML_VALUE_YES)) {
  246. return NLB_RemoteControl::Yes;
  247. } else if (!lstrcmpi(pwszType, NLB_XML_VALUE_NO)) {
  248. return NLB_RemoteControl::No;
  249. }
  250. return NLB_RemoteControl::Invalid;
  251. }
  252. /*
  253. * Method:
  254. * Description:
  255. * Author:
  256. */
  257. HRESULT NLB_XMLParser::PrintTree(MSXML2::IXMLDOMNode * pNode, int level) {
  258. MSXML2::IXMLDOMNamedNodeMap * pAttrs = NULL;
  259. MSXML2::IXMLDOMNode * pChild = NULL;
  260. MSXML2::IXMLDOMNode * pNext = NULL;
  261. BSTR BNodeName = NULL;
  262. VARIANT value;
  263. pNode->get_nodeName(&BNodeName);
  264. for (int i = 0; i < level; i++)
  265. printf(" ");
  266. printf("%ls", BNodeName);
  267. if (!lstrcmpi(BNodeName, L"#text")) {
  268. pNode->get_nodeValue(&value);
  269. if (value.vt == VT_BSTR)
  270. printf(" %ls", V_BSTR(&value));
  271. VariantClear(&value);
  272. }
  273. SysFreeString(BNodeName);
  274. if (SUCCEEDED(pNode->get_attributes(&pAttrs)) && (pAttrs != NULL)) {
  275. pAttrs->nextNode(&pChild);
  276. while (pChild) {
  277. BSTR name;
  278. VARIANT value;
  279. pChild->get_nodeName(&name);
  280. printf(" %ls='", name);
  281. SysFreeString(name);
  282. pChild->get_nodeValue(&value);
  283. if (value.vt == VT_BSTR)
  284. printf("%ls", V_BSTR(&value));
  285. printf("'");
  286. VariantClear(&value);
  287. pChild->Release();
  288. pAttrs->nextNode(&pChild);
  289. }
  290. pAttrs->Release();
  291. }
  292. printf("\n");
  293. pNode->get_firstChild(&pChild);
  294. while (pChild) {
  295. PrintTree(pChild, level + 1);
  296. pChild->get_nextSibling(&pNext);
  297. pChild->Release();
  298. pChild = pNext;
  299. }
  300. return S_OK;
  301. }
  302. /*
  303. * Method:
  304. * Description:
  305. * Author:
  306. */
  307. HRESULT NLB_XMLParser::ParseClusterPortRules (MSXML2::IXMLDOMNode * pNode, NLB_Cluster * pCluster) {
  308. HRESULT hr = S_OK;
  309. //CleanUp:
  310. return hr;
  311. }
  312. /*
  313. * Method:
  314. * Description:
  315. * Author:
  316. */
  317. HRESULT NLB_XMLParser::ParseHost (MSXML2::IXMLDOMNode * pNode, NLB_Host * pHost) {
  318. MSXML2::IXMLDOMElement * pElement = NULL;
  319. MSXML2::IXMLDOMNode * pChild = NULL;
  320. MSXML2::IXMLDOMNode * pNext = NULL;
  321. BSTR BNodeName = NULL;
  322. BSTR BAttribute = NULL;
  323. VARIANT value;
  324. HRESULT hr = S_OK;
  325. CHECKHR(pNode->QueryInterface(MSXML2::IID_IXMLDOMElement,(void**)&pElement));
  326. CHECKALLOC((BAttribute = SysAllocString(NLB_XML_ATTRIBUTE_NAME)));
  327. CHECKHR(pElement->getAttribute(BAttribute, &value));
  328. if (hr == S_OK)
  329. pHost->Name.SetName(V_BSTR(&value));
  330. else if (hr == S_FALSE)
  331. hr = S_OK;
  332. VariantClear(&value);
  333. SAFEFREESTRING(BAttribute);
  334. CHECKALLOC((BAttribute = SysAllocString(NLB_XML_ATTRIBUTE_TEXT)));
  335. CHECKHR(pElement->getAttribute(BAttribute, &value));
  336. if (hr == S_OK)
  337. pHost->Label.SetText(V_BSTR(&value));
  338. else if (hr == S_FALSE)
  339. hr = S_OK;
  340. VariantClear(&value);
  341. SAFEFREESTRING(BAttribute);
  342. CHECKALLOC((BAttribute = SysAllocString(NLB_XML_ATTRIBUTE_HOSTID)));
  343. CHECKHR(pElement->getAttribute(BAttribute, &value));
  344. if (hr == S_OK)
  345. pHost->HostID.SetID(_wtoi(V_BSTR(&value)));
  346. else if (hr == S_FALSE)
  347. hr = S_OK;
  348. VariantClear(&value);
  349. SAFEFREESTRING(BAttribute);
  350. CHECKALLOC((BAttribute = SysAllocString(NLB_XML_ATTRIBUTE_STATE)));
  351. CHECKHR(pElement->getAttribute(BAttribute, &value));
  352. if (hr == S_OK)
  353. pHost->HostState.SetState(StringToHostState(V_BSTR(&value)));
  354. else if (hr == S_FALSE)
  355. hr = S_OK;
  356. VariantClear(&value);
  357. SAFEFREESTRING(BAttribute);
  358. SAFERELEASE(pElement);
  359. pNode->get_firstChild(&pChild);
  360. while (pChild) {
  361. pChild->get_nodeName(&BNodeName);
  362. CHECKALLOC(BNodeName);
  363. if (!lstrcmpi(BNodeName, NLB_XML_ELEMENT_HOSTNAME)) {
  364. pChild->get_firstChild(&pNext);
  365. pNext->get_nodeValue(&value);
  366. if (value.vt != VT_BSTR) {
  367. hr = E_FAIL;
  368. goto CleanUp;
  369. }
  370. pHost->HostName.SetName(V_BSTR(&value));
  371. VariantClear(&value);
  372. SAFERELEASE(pNext);
  373. } else if (!lstrcmp(BNodeName, NLB_XML_ELEMENT_IPADDRESS)) {
  374. NLB_IPAddress::NLB_IPAddressType Type;
  375. NLB_IPAddress IPAddress;
  376. CHECKHR(ParseIPAddress(pChild, &IPAddress));
  377. IPAddress.GetIPAddressType(&Type);
  378. switch (Type) {
  379. case NLB_IPAddress::Connection:
  380. CopyMemory(&pHost->ConnectionIPAddress, &IPAddress, sizeof(NLB_IPAddress));
  381. break;
  382. case NLB_IPAddress::Dedicated:
  383. CopyMemory(&pHost->DedicatedIPAddress, &IPAddress, sizeof(NLB_IPAddress));
  384. break;
  385. case NLB_IPAddress::IGMP:
  386. case NLB_IPAddress::Virtual:
  387. case NLB_IPAddress::Primary:
  388. case NLB_IPAddress::Secondary:
  389. default:
  390. hr = E_FAIL;
  391. goto CleanUp;
  392. break;
  393. }
  394. } else if (!lstrcmp(BNodeName, NLB_XML_ELEMENT_ADAPTER)) {
  395. CHECKHR(ParseAdapter(pChild, &pHost->Adapter));
  396. } else {
  397. hr = E_FAIL;
  398. goto CleanUp;
  399. }
  400. pChild->get_nextSibling(&pNext);
  401. pChild->Release();
  402. pChild = pNext;
  403. pNext = NULL;
  404. SAFEFREESTRING(BNodeName);
  405. }
  406. CleanUp:
  407. SAFERELEASE(pChild);
  408. SAFERELEASE(pNext);
  409. SAFEFREESTRING(BNodeName);
  410. SAFEFREESTRING(BAttribute);
  411. return hr;
  412. }
  413. /*
  414. * Method:
  415. * Description:
  416. * Author:
  417. */
  418. HRESULT NLB_XMLParser::ParseClusterHosts (MSXML2::IXMLDOMNode * pNode, NLB_Cluster * pCluster) {
  419. MSXML2::IXMLDOMNode * pChild = NULL;
  420. MSXML2::IXMLDOMNode * pNext = NULL;
  421. BSTR BNodeName = NULL;
  422. VARIANT value;
  423. HRESULT hr = S_OK;
  424. pNode->get_firstChild(&pChild);
  425. while (pChild) {
  426. pChild->get_nodeName(&BNodeName);
  427. CHECKALLOC(BNodeName);
  428. if (!lstrcmpi(BNodeName, NLB_XML_ELEMENT_HOST)) {
  429. NLB_Host Host;
  430. CHECKHR(ParseHost(pChild, &Host));
  431. pCluster->HostList.push_back(Host);
  432. } else {
  433. hr = E_FAIL;
  434. goto CleanUp;
  435. }
  436. pChild->get_nextSibling(&pNext);
  437. pChild->Release();
  438. pChild = pNext;
  439. pNext = NULL;
  440. SAFEFREESTRING(BNodeName);
  441. }
  442. CleanUp:
  443. SAFERELEASE(pChild);
  444. SAFERELEASE(pNext);
  445. SAFEFREESTRING(BNodeName);
  446. return hr;
  447. }
  448. /*
  449. * Method:
  450. * Description:
  451. * Author:
  452. */
  453. HRESULT NLB_XMLParser::ParseRemoteControl (MSXML2::IXMLDOMNode * pNode, NLB_RemoteControl * pControl) {
  454. MSXML2::IXMLDOMElement * pElement = NULL;
  455. MSXML2::IXMLDOMNode * pChild = NULL;
  456. MSXML2::IXMLDOMNode * pNext = NULL;
  457. BSTR BAttribute = NULL;
  458. BSTR BNodeName = NULL;
  459. HRESULT hr = S_OK;
  460. VARIANT value;
  461. CHECKHR(pNode->QueryInterface(MSXML2::IID_IXMLDOMElement,(void**)&pElement));
  462. CHECKALLOC((BAttribute = SysAllocString(NLB_XML_ATTRIBUTE_ENABLED)));
  463. CHECKHR(pElement->getAttribute(BAttribute, &value));
  464. pControl->SetEnabled(StringToRemoteControlEnabled(V_BSTR(&value)));
  465. VariantClear(&value);
  466. SAFERELEASE(pElement);
  467. pNode->get_firstChild(&pChild);
  468. while (pChild) {
  469. pChild->get_nodeName(&BNodeName);
  470. CHECKALLOC(BNodeName);
  471. if (!lstrcmp(BNodeName, NLB_XML_ELEMENT_PASSWORD)) {
  472. NLB_RemoteControl::NLB_RemoteControlEnabled Enabled;
  473. pControl->GetEnabled(&Enabled);
  474. if (Enabled == NLB_RemoteControl::Yes) {
  475. pChild->get_firstChild(&pNext);
  476. pNext->get_nodeValue(&value);
  477. if (value.vt != VT_BSTR) {
  478. hr = E_FAIL;
  479. goto CleanUp;
  480. }
  481. pControl->SetPassword(V_BSTR(&value));
  482. VariantClear(&value);
  483. SAFERELEASE(pNext);
  484. } else {
  485. hr = E_FAIL;
  486. goto CleanUp;
  487. }
  488. } else {
  489. hr = E_FAIL;
  490. goto CleanUp;
  491. }
  492. pChild->get_nextSibling(&pNext);
  493. pChild->Release();
  494. pChild = pNext;
  495. pNext = NULL;
  496. SAFEFREESTRING(BNodeName);
  497. }
  498. CleanUp:
  499. SAFERELEASE(pElement);
  500. SAFERELEASE(pChild);
  501. SAFERELEASE(pNext);
  502. SAFEFREESTRING(BNodeName);
  503. SAFEFREESTRING(BAttribute);
  504. return hr;
  505. }
  506. /*
  507. * Method:
  508. * Description:
  509. * Author:
  510. */
  511. HRESULT NLB_XMLParser::ParseAdapter (MSXML2::IXMLDOMNode * pNode, NLB_Adapter * pAdapter) {
  512. MSXML2::IXMLDOMNode * pChild = NULL;
  513. MSXML2::IXMLDOMNode * pNext = NULL;
  514. BSTR BNodeName = NULL;
  515. HRESULT hr = S_OK;
  516. VARIANT value;
  517. pNode->get_firstChild(&pChild);
  518. while (pChild) {
  519. pChild->get_nodeName(&BNodeName);
  520. CHECKALLOC(BNodeName);
  521. if (!lstrcmp(BNodeName, NLB_XML_ELEMENT_GUID)) {
  522. pChild->get_firstChild(&pNext);
  523. pNext->get_nodeValue(&value);
  524. if (value.vt != VT_BSTR) {
  525. hr = E_FAIL;
  526. goto CleanUp;
  527. }
  528. pAdapter->SetIdentifiedBy(NLB_Adapter::ByGUID);
  529. pAdapter->SetAdapter(V_BSTR(&value));
  530. VariantClear(&value);
  531. SAFERELEASE(pNext);
  532. } else if (!lstrcmp(BNodeName, NLB_XML_ELEMENT_NAME)) {
  533. pChild->get_firstChild(&pNext);
  534. pNext->get_nodeValue(&value);
  535. if (value.vt != VT_BSTR) {
  536. hr = E_FAIL;
  537. goto CleanUp;
  538. }
  539. pAdapter->SetIdentifiedBy(NLB_Adapter::ByName);
  540. pAdapter->SetAdapter(V_BSTR(&value));
  541. VariantClear(&value);
  542. SAFERELEASE(pNext);
  543. } else {
  544. hr = E_FAIL;
  545. goto CleanUp;
  546. }
  547. pChild->get_nextSibling(&pNext);
  548. pChild->Release();
  549. pChild = pNext;
  550. pNext = NULL;
  551. SAFEFREESTRING(BNodeName);
  552. }
  553. CleanUp:
  554. SAFERELEASE(pChild);
  555. SAFERELEASE(pNext);
  556. SAFEFREESTRING(BNodeName);
  557. return hr;
  558. }
  559. /*
  560. * Method:
  561. * Description:
  562. * Author:
  563. */
  564. HRESULT NLB_XMLParser::ParseIPAddress (MSXML2::IXMLDOMNode * pNode, NLB_IPAddress * pIPAddress) {
  565. MSXML2::IXMLDOMElement * pElement = NULL;
  566. MSXML2::IXMLDOMNode * pChild = NULL;
  567. MSXML2::IXMLDOMNode * pNext = NULL;
  568. BSTR BAttribute = NULL;
  569. BSTR BNodeName = NULL;
  570. HRESULT hr = S_OK;
  571. VARIANT value;
  572. CHECKHR(pNode->QueryInterface(MSXML2::IID_IXMLDOMElement,(void**)&pElement));
  573. CHECKALLOC((BAttribute = SysAllocString(NLB_XML_ATTRIBUTE_TYPE)));
  574. CHECKHR(pElement->getAttribute(BAttribute, &value));
  575. pIPAddress->SetIPAddressType(StringToIPAddressType(V_BSTR(&value)));
  576. VariantClear(&value);
  577. SAFERELEASE(pElement);
  578. pNode->get_firstChild(&pChild);
  579. while (pChild) {
  580. pChild->get_nodeName(&BNodeName);
  581. CHECKALLOC(BNodeName);
  582. if (!lstrcmp(BNodeName, NLB_XML_ELEMENT_ADDRESS)) {
  583. pChild->get_firstChild(&pNext);
  584. pNext->get_nodeValue(&value);
  585. if (value.vt != VT_BSTR) {
  586. hr = E_FAIL;
  587. goto CleanUp;
  588. }
  589. pIPAddress->SetIPAddress(V_BSTR(&value));
  590. VariantClear(&value);
  591. SAFERELEASE(pNext);
  592. } else if (!lstrcmp(BNodeName, NLB_XML_ELEMENT_SUBNETMASK)) {
  593. pChild->get_firstChild(&pNext);
  594. pNext->get_nodeValue(&value);
  595. if (value.vt != VT_BSTR) {
  596. hr = E_FAIL;
  597. goto CleanUp;
  598. }
  599. pIPAddress->SetSubnetMask(V_BSTR(&value));
  600. VariantClear(&value);
  601. SAFERELEASE(pNext);
  602. } else if (!lstrcmp(BNodeName, NLB_XML_ELEMENT_ADAPTER)) {
  603. NLB_IPAddress::NLB_IPAddressType Type;
  604. pIPAddress->GetIPAddressType(&Type);
  605. switch (Type) {
  606. case NLB_IPAddress::Connection:
  607. case NLB_IPAddress::Dedicated:
  608. CHECKHR(ParseAdapter(pChild, pIPAddress->GetAdapter()));
  609. break;
  610. case NLB_IPAddress::Primary:
  611. case NLB_IPAddress::Secondary:
  612. case NLB_IPAddress::IGMP:
  613. case NLB_IPAddress::Virtual:
  614. // SetParseError(NLB_XML_PARSE_ERROR_IPADDRESS_ADAPTER_CODE, NLB_XML_PARSE_ERROR_IPADDRESS_ADAPTER_REASON);
  615. default:
  616. hr = E_FAIL;
  617. goto CleanUp;
  618. break;
  619. }
  620. } else {
  621. hr = E_FAIL;
  622. goto CleanUp;
  623. }
  624. pChild->get_nextSibling(&pNext);
  625. pChild->Release();
  626. pChild = pNext;
  627. pNext = NULL;
  628. SAFEFREESTRING(BNodeName);
  629. }
  630. CleanUp:
  631. SAFERELEASE(pElement);
  632. SAFERELEASE(pChild);
  633. SAFERELEASE(pNext);
  634. SAFEFREESTRING(BNodeName);
  635. SAFEFREESTRING(BAttribute);
  636. return hr;
  637. }
  638. /*
  639. * Method:
  640. * Description:
  641. * Author:
  642. */
  643. HRESULT NLB_XMLParser::ParseClusterProperties (MSXML2::IXMLDOMNode * pNode, NLB_Cluster * pCluster) {
  644. MSXML2::IXMLDOMNode * pChild = NULL;
  645. MSXML2::IXMLDOMNode * pNext = NULL;
  646. BSTR BNodeName = NULL;
  647. HRESULT hr = S_OK;
  648. VARIANT value;
  649. pNode->get_firstChild(&pChild);
  650. while (pChild) {
  651. pChild->get_nodeName(&BNodeName);
  652. CHECKALLOC(BNodeName);
  653. if (!lstrcmp(BNodeName, NLB_XML_ELEMENT_IPADDRESS)) {
  654. NLB_IPAddress::NLB_IPAddressType Type;
  655. NLB_IPAddress IPAddress;
  656. CHECKHR(ParseIPAddress(pChild, &IPAddress));
  657. IPAddress.GetIPAddressType(&Type);
  658. switch (Type) {
  659. case NLB_IPAddress::Primary:
  660. CopyMemory(&pCluster->PrimaryIPAddress, &IPAddress, sizeof(NLB_IPAddress));
  661. break;
  662. case NLB_IPAddress::Secondary:
  663. pCluster->SecondaryIPAddressList.push_back(IPAddress);
  664. break;
  665. case NLB_IPAddress::IGMP:
  666. CopyMemory(&pCluster->IGMPMulticastIPAddress, &IPAddress, sizeof(NLB_IPAddress));
  667. break;
  668. case NLB_IPAddress::Virtual:
  669. case NLB_IPAddress::Connection:
  670. case NLB_IPAddress::Dedicated:
  671. default:
  672. hr = E_FAIL;
  673. goto CleanUp;
  674. break;
  675. }
  676. } else if (!lstrcmp(BNodeName, NLB_XML_ELEMENT_DOMAINNAME)) {
  677. pChild->get_firstChild(&pNext);
  678. pNext->get_nodeValue(&value);
  679. if (value.vt != VT_BSTR) {
  680. hr = E_FAIL;
  681. goto CleanUp;
  682. }
  683. pCluster->DomainName.SetDomain(V_BSTR(&value));
  684. VariantClear(&value);
  685. SAFERELEASE(pNext);
  686. } else if (!lstrcmp(BNodeName, NLB_XML_ELEMENT_NETWORKADDRESS)) {
  687. pChild->get_firstChild(&pNext);
  688. pNext->get_nodeValue(&value);
  689. if (value.vt != VT_BSTR) {
  690. hr = E_FAIL;
  691. goto CleanUp;
  692. }
  693. pCluster->NetworkAddress.SetAddress(V_BSTR(&value));
  694. VariantClear(&value);
  695. SAFERELEASE(pNext);
  696. } else if (!lstrcmp(BNodeName, NLB_XML_ELEMENT_CLUSTER_MODE)) {
  697. pChild->get_firstChild(&pNext);
  698. pNext->get_nodeValue(&value);
  699. if (value.vt != VT_BSTR) {
  700. hr = E_FAIL;
  701. goto CleanUp;
  702. }
  703. pCluster->ClusterMode.SetMode(StringToClusterMode(V_BSTR(&value)));
  704. VariantClear(&value);
  705. SAFERELEASE(pNext);
  706. } else if (!lstrcmp(BNodeName, NLB_XML_ELEMENT_REMOTE_CONTROL)) {
  707. CHECKHR(ParseRemoteControl(pChild, &pCluster->RemoteControl));
  708. } else {
  709. hr = E_FAIL;
  710. goto CleanUp;
  711. }
  712. pChild->get_nextSibling(&pNext);
  713. pChild->Release();
  714. pChild = pNext;
  715. pNext = NULL;
  716. SAFEFREESTRING(BNodeName);
  717. }
  718. CleanUp:
  719. SAFERELEASE(pChild);
  720. SAFERELEASE(pNext);
  721. SAFEFREESTRING(BNodeName);
  722. return hr;
  723. }
  724. /*
  725. * Method:
  726. * Description:
  727. * Author:
  728. */
  729. HRESULT NLB_XMLParser::ParseCluster (MSXML2::IXMLDOMNode * pNode, NLB_Cluster * pCluster) {
  730. MSXML2::IXMLDOMElement * pElement = NULL;
  731. MSXML2::IXMLDOMNode * pChild = NULL;
  732. MSXML2::IXMLDOMNode * pNext = NULL;
  733. BSTR BNodeName = NULL;
  734. BSTR BAttribute = NULL;
  735. VARIANT value;
  736. HRESULT hr = S_OK;
  737. CHECKHR(pNode->QueryInterface(MSXML2::IID_IXMLDOMElement,(void**)&pElement));
  738. CHECKALLOC((BAttribute = SysAllocString(NLB_XML_ATTRIBUTE_NAME)));
  739. CHECKHR(pElement->getAttribute(BAttribute, &value));
  740. if (hr == S_OK)
  741. pCluster->Name.SetName(V_BSTR(&value));
  742. else if (hr == S_FALSE)
  743. hr = S_OK;
  744. VariantClear(&value);
  745. SAFEFREESTRING(BAttribute);
  746. CHECKALLOC((BAttribute = SysAllocString(NLB_XML_ATTRIBUTE_TEXT)));
  747. CHECKHR(pElement->getAttribute(BAttribute, &value));
  748. if (hr == S_OK)
  749. pCluster->Label.SetText(V_BSTR(&value));
  750. else if (hr == S_FALSE)
  751. hr = S_OK;
  752. VariantClear(&value);
  753. SAFEFREESTRING(BAttribute);
  754. SAFERELEASE(pElement);
  755. pNode->get_firstChild(&pChild);
  756. while (pChild) {
  757. pChild->get_nodeName(&BNodeName);
  758. CHECKALLOC(BNodeName);
  759. if (!lstrcmpi(BNodeName, NLB_XML_ELEMENT_PROPERTIES)) {
  760. CHECKHR(ParseClusterProperties(pChild, pCluster));
  761. } else if (!lstrcmpi(BNodeName, NLB_XML_ELEMENT_HOSTS)) {
  762. CHECKHR(ParseClusterHosts(pChild, pCluster));
  763. } else if (!lstrcmpi(BNodeName, NLB_XML_ELEMENT_PORTRULES)) {
  764. CHECKHR(ParseClusterPortRules(pChild, pCluster));
  765. } else {
  766. hr = E_FAIL;
  767. goto CleanUp;
  768. }
  769. pChild->get_nextSibling(&pNext);
  770. pChild->Release();
  771. pChild = pNext;
  772. pNext = NULL;
  773. SAFEFREESTRING(BNodeName);
  774. }
  775. CleanUp:
  776. SAFERELEASE(pChild);
  777. SAFERELEASE(pNext);
  778. SAFEFREESTRING(BNodeName);
  779. SAFEFREESTRING(BAttribute);
  780. return hr;
  781. }
  782. /*
  783. * Method:
  784. * Description:
  785. * Author:
  786. */
  787. HRESULT NLB_XMLParser::Parse (WCHAR * wszFileName, vector<NLB_Cluster> * pClusters) {
  788. MSXML2::IXMLDOMNodeList * pList = NULL;
  789. MSXML2::IXMLDOMNode * pNode = NULL;
  790. BSTR BURL = NULL;
  791. BSTR BTag = NULL;
  792. HRESULT hr = S_OK;
  793. NLB_Cluster cluster;
  794. LONG length;
  795. LONG index;
  796. CoInitialize(NULL);
  797. CHECKHR(CoCreateInstance(MSXML2::CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER,
  798. MSXML2::IID_IXMLDOMDocument2, (void**)&pDoc));
  799. CHECKALLOC(pDoc);
  800. CHECKALLOC((BURL = SysAllocString(wszFileName)));
  801. CHECKALLOC((BTag = SysAllocString(NLB_XML_ELEMENT_CLUSTER)));
  802. CHECKHR(LoadDocument(BURL));
  803. CHECKHR(pDoc->getElementsByTagName(BTag, &pList));
  804. CHECKALLOC(pList);
  805. CHECKHR(pList->get_length(&length));
  806. CHECKHR(pList->reset());
  807. for (index = 0; index < length; index++) {
  808. NLB_Cluster cluster;
  809. CHECKHR(pList->get_item(index, &pNode));
  810. CHECKALLOC(pNode);
  811. CHECKHR(ParseCluster(pNode, &cluster));
  812. ClusterList.push_back(cluster);
  813. SAFERELEASE(pNode);
  814. }
  815. *pClusters = ClusterList;
  816. CleanUp:
  817. SAFERELEASE(pList);
  818. SAFERELEASE(pNode);
  819. SAFERELEASE(pDoc);
  820. SAFEFREESTRING(BURL);
  821. SAFEFREESTRING(BTag);
  822. CoUninitialize();
  823. return hr;
  824. }
  825. /*
  826. * Method:
  827. * Description:
  828. * Author:
  829. */
  830. HRESULT NLB_XMLParser::Parse (WCHAR * wszFileName) {
  831. BSTR BURL = NULL;
  832. HRESULT hr = S_OK;
  833. CoInitialize(NULL);
  834. CHECKHR(CoCreateInstance(MSXML2::CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER,
  835. MSXML2::IID_IXMLDOMDocument2, (void**)&pDoc));
  836. CHECKALLOC(pDoc);
  837. CHECKALLOC((BURL = SysAllocString(wszFileName)));
  838. CHECKHR(LoadDocument(BURL));
  839. CleanUp:
  840. SAFERELEASE(pDoc);
  841. SAFEFREESTRING(BURL);
  842. CoUninitialize();
  843. return hr;
  844. }
  845. /*
  846. * Method:
  847. * Description:
  848. * Author:
  849. */
  850. HRESULT NLB_XMLParser::Parse (WCHAR * wszFileName, bool bPrintTree) {
  851. MSXML2::IXMLDOMNode * pNode = NULL;
  852. BSTR BURL = NULL;
  853. HRESULT hr = S_OK;
  854. CoInitialize(NULL);
  855. CHECKHR(CoCreateInstance(MSXML2::CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER,
  856. MSXML2::IID_IXMLDOMDocument2, (void**)&pDoc));
  857. CHECKALLOC(pDoc);
  858. CHECKALLOC((BURL = SysAllocString(wszFileName)));
  859. CHECKHR(LoadDocument(BURL));
  860. if (bPrintTree) {
  861. CHECKHR(pDoc->QueryInterface(MSXML2::IID_IXMLDOMNode,(void**)&pNode));
  862. CHECKALLOC(pNode);
  863. CHECKHR(PrintTree(pNode, 0));
  864. }
  865. CleanUp:
  866. SAFERELEASE(pDoc);
  867. SAFERELEASE(pNode);
  868. SAFEFREESTRING(BURL);
  869. CoUninitialize();
  870. return hr;
  871. }
  872. /*
  873. * Method:
  874. * Description:
  875. * Author:
  876. */
  877. void NLB_XMLParser::Print () {
  878. Print(ClusterList);
  879. }
  880. /*
  881. * Method:
  882. * Description:
  883. * Author:
  884. */
  885. void NLB_XMLParser::Print (vector<NLB_Cluster> Clusters) {
  886. vector<NLB_Cluster>::iterator icluster;
  887. for (icluster = Clusters.begin(); icluster != Clusters.end(); icluster++) {
  888. vector<NLB_IPAddress>::iterator iaddress;
  889. vector<NLB_Host>::iterator ihost;
  890. NLB_Cluster * cluster = icluster;
  891. NLB_RemoteControl::NLB_RemoteControlEnabled enabled;
  892. NLB_ClusterMode::NLB_ClusterModeType mode;
  893. NLB_Adapter::NLB_AdapterIdentifier by;
  894. NLB_Adapter * adapter;
  895. PWSTR buffer;
  896. if (cluster->Name.GetName(&buffer))
  897. printf("\nCluster name: %ls ", buffer);
  898. SAFEFREESTRING(buffer);
  899. if (cluster->Label.GetText(&buffer))
  900. printf("(%ls)", buffer);
  901. printf("\n");
  902. SAFEFREESTRING(buffer);
  903. if (cluster->PrimaryIPAddress.GetIPAddress(&buffer))
  904. printf(" Primary Cluster IP Address: %ls\n", buffer);
  905. SAFEFREESTRING(buffer);
  906. if (cluster->PrimaryIPAddress.GetSubnetMask(&buffer))
  907. printf(" Subnet Mask: %ls\n", buffer);
  908. SAFEFREESTRING(buffer);
  909. if (cluster->ClusterMode.GetMode(&mode)) {
  910. switch (mode) {
  911. case NLB_ClusterMode::Unicast:
  912. printf(" Cluster Mode: Unicast\n");
  913. break;
  914. case NLB_ClusterMode::Multicast:
  915. printf(" Cluster Mode: Multicast\n");
  916. break;
  917. case NLB_ClusterMode::IGMP:
  918. printf(" Cluster Mode: IGMP\n");
  919. break;
  920. default:
  921. break;
  922. }
  923. }
  924. if (cluster->IGMPMulticastIPAddress.GetIPAddress(&buffer))
  925. printf(" IGMP Multicast IP Address: %ls\n", buffer);
  926. SAFEFREESTRING(buffer);
  927. if (cluster->DomainName.GetDomain(&buffer))
  928. printf(" Domain Name: %ls\n", buffer);
  929. SAFEFREESTRING(buffer);
  930. if (cluster->NetworkAddress.GetAddress(&buffer))
  931. printf(" Network Address: %ls\n", buffer);
  932. SAFEFREESTRING(buffer);
  933. if (cluster->RemoteControl.GetEnabled(&enabled)) {
  934. switch (enabled) {
  935. case NLB_RemoteControl::Yes:
  936. printf(" Remote Control: Enabled ");
  937. if (cluster->RemoteControl.GetPassword(&buffer))
  938. printf("(Password=%ls)", buffer);
  939. printf("\n");
  940. SAFEFREESTRING(buffer);
  941. break;
  942. case NLB_RemoteControl::No:
  943. printf(" Remote Control: Disabled\n");
  944. break;
  945. default:
  946. break;
  947. }
  948. }
  949. for (iaddress = cluster->SecondaryIPAddressList.begin(); iaddress != cluster->SecondaryIPAddressList.end(); iaddress++) {
  950. NLB_IPAddress * address = iaddress;
  951. if (address->GetIPAddress(&buffer))
  952. printf(" Secondary Cluster IP Address: %ls\n", buffer);
  953. SAFEFREESTRING(buffer);
  954. if (address->GetSubnetMask(&buffer))
  955. printf(" Subnet Mask: %ls\n", buffer);
  956. SAFEFREESTRING(buffer);
  957. adapter = address->GetAdapter();
  958. if (adapter->GetIdentifiedBy(&by)) {
  959. adapter->GetAdapter(&buffer);
  960. switch (by) {
  961. case NLB_Adapter::ByName:
  962. printf(" Adapter Name: %ls\n", buffer);
  963. break;
  964. case NLB_Adapter::ByGUID:
  965. printf(" Adapter GUID: %ls\n", buffer);
  966. break;
  967. default:
  968. break;
  969. }
  970. }
  971. SAFEFREESTRING(buffer);
  972. }
  973. for (ihost = cluster->HostList.begin(); ihost != cluster->HostList.end(); ihost++) {
  974. NLB_HostState::NLB_HostStateType state;
  975. NLB_Host * host = ihost;
  976. int id;
  977. if (host->Name.GetName(&buffer))
  978. printf("\nHost name: %ls ", buffer);
  979. SAFEFREESTRING(buffer);
  980. if (host->Label.GetText(&buffer))
  981. printf("(%ls)", buffer);
  982. printf("\n");
  983. SAFEFREESTRING(buffer);
  984. if (host->Adapter.GetIdentifiedBy(&by)) {
  985. host->Adapter.GetAdapter(&buffer);
  986. switch (by) {
  987. case NLB_Adapter::ByName:
  988. printf(" Adapter Name: %ls\n", buffer);
  989. break;
  990. case NLB_Adapter::ByGUID:
  991. printf(" Adapter GUID: %ls\n", buffer);
  992. break;
  993. default:
  994. break;
  995. }
  996. }
  997. SAFEFREESTRING(buffer);
  998. if (host->HostID.GetID(&id))
  999. printf(" Host ID: %d\n", id);
  1000. if (host->HostState.GetState(&state)) {
  1001. switch (state) {
  1002. case NLB_HostState::Started:
  1003. printf(" Host State: Started\n");
  1004. break;
  1005. case NLB_HostState::Stopped:
  1006. printf(" Host State: Stopped\n");
  1007. break;
  1008. case NLB_HostState::Suspended:
  1009. printf(" Host State: Suspended\n");
  1010. break;
  1011. default:
  1012. break;
  1013. }
  1014. }
  1015. if (host->HostName.GetName(&buffer))
  1016. printf(" Hostname: %ls\n", buffer);
  1017. SAFEFREESTRING(buffer);
  1018. if (host->DedicatedIPAddress.GetIPAddress(&buffer))
  1019. printf(" Dedicated Cluster IP Address: %ls\n", buffer);
  1020. SAFEFREESTRING(buffer);
  1021. if (host->DedicatedIPAddress.GetSubnetMask(&buffer))
  1022. printf(" Subnet Mask: %ls\n", buffer);
  1023. SAFEFREESTRING(buffer);
  1024. adapter = host->DedicatedIPAddress.GetAdapter();
  1025. if (adapter->GetIdentifiedBy(&by)) {
  1026. adapter->GetAdapter(&buffer);
  1027. switch (by) {
  1028. case NLB_Adapter::ByName:
  1029. printf(" Adapter Name: %ls\n", buffer);
  1030. break;
  1031. case NLB_Adapter::ByGUID:
  1032. printf(" Adapter GUID: %ls\n", buffer);
  1033. break;
  1034. default:
  1035. break;
  1036. }
  1037. }
  1038. SAFEFREESTRING(buffer);
  1039. if (host->ConnectionIPAddress.GetIPAddress(&buffer))
  1040. printf(" Connection Cluster IP Address: %ls\n", buffer);
  1041. SAFEFREESTRING(buffer);
  1042. if (host->ConnectionIPAddress.GetSubnetMask(&buffer))
  1043. printf(" Subnet Mask: %ls\n", buffer);
  1044. SAFEFREESTRING(buffer);
  1045. adapter = host->ConnectionIPAddress.GetAdapter();
  1046. if (adapter->GetIdentifiedBy(&by)) {
  1047. adapter->GetAdapter(&buffer);
  1048. switch (by) {
  1049. case NLB_Adapter::ByName:
  1050. printf(" Adapter Name: %ls\n", buffer);
  1051. break;
  1052. case NLB_Adapter::ByGUID:
  1053. printf(" Adapter GUID: %ls\n", buffer);
  1054. break;
  1055. default:
  1056. break;
  1057. }
  1058. }
  1059. SAFEFREESTRING(buffer);
  1060. }
  1061. }
  1062. }