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.

2372 lines
63 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. clnetcfg.c
  5. Abstract:
  6. System network configuration grovelling routines
  7. Author:
  8. Mike Massa (mikemas) May 19, 1997
  9. Revision History:
  10. Who When What
  11. -------- -------- ----------------------------------------------
  12. mikemas 05-19-97 created
  13. --*/
  14. #include <nt.h>
  15. #include <ntrtl.h>
  16. #include <nturtl.h>
  17. #include <windows.h>
  18. #include <cluster.h>
  19. #include <clusrpc.h>
  20. #include <clnetcfg.h>
  21. #include <wchar.h>
  22. //
  23. // Private constants
  24. //
  25. #define CLNET_DEFAULT_NETWORK_PRIORITY 0xffffffff
  26. //
  27. // Private Data
  28. //
  29. LPFN_CLNETPRINT pClNetPrint = NULL;
  30. LPFN_CLNETLOGEVENT pClNetLogEvent = NULL;
  31. LPFN_CLNETLOGEVENT1 pClNetLogEvent1 = NULL;
  32. LPFN_CLNETLOGEVENT2 pClNetLogEvent2 = NULL;
  33. LPFN_CLNETLOGEVENT3 pClNetLogEvent3 = NULL;
  34. WCHAR ClNetpEmptyString[] = L"";
  35. //
  36. // Private Macros
  37. //
  38. #if DBG
  39. #define ClNetDbgPrint(arg) (*pClNetPrint) arg
  40. #else
  41. #define ClNetDbgPrint(arg)
  42. #endif
  43. //
  44. // Private utility routines
  45. //
  46. VOID
  47. ClNetpConsumeAdaptersOnNetwork(
  48. IN PCLRTL_NET_ADAPTER_ENUM AdapterEnum,
  49. IN LPWSTR NetworkAddress
  50. )
  51. {
  52. PCLRTL_NET_ADAPTER_INFO adapterInfo;
  53. PCLRTL_NET_INTERFACE_INFO adapterIfInfo;
  54. ClNetDbgPrint((
  55. LOG_NOISE,
  56. "[ClNet] Consuming all adapters on IP network %1!ws!.\n",
  57. NetworkAddress
  58. ));
  59. //
  60. // Walk the adapter enum and consume all other adapters
  61. // attached to this network.
  62. //
  63. for (adapterInfo = AdapterEnum->AdapterList;
  64. adapterInfo != NULL;
  65. adapterInfo = adapterInfo->Next
  66. )
  67. {
  68. if (adapterInfo->Ignore == FALSE) {
  69. adapterIfInfo = ClRtlFindNetInterfaceByNetworkAddress(
  70. adapterInfo,
  71. NetworkAddress
  72. );
  73. if (adapterIfInfo != NULL) {
  74. //
  75. // This is a duplicate adapter.
  76. //
  77. ClNetDbgPrint((
  78. LOG_NOISE,
  79. "[ClNet] Consumed adapter '%1!ws!'.\n",
  80. adapterInfo->DeviceName
  81. ));
  82. adapterInfo->Ignore = TRUE;
  83. }
  84. }
  85. }
  86. ClNetDbgPrint((
  87. LOG_NOISE,
  88. "[ClNet] Finished consuming all adapters on IP network %1!ws!.\n",
  89. NetworkAddress
  90. ));
  91. return;
  92. } // ClNetpConsumeAdaptersOnNetwork
  93. LPWSTR
  94. ClNetpCloneString(
  95. LPWSTR String
  96. )
  97. {
  98. LPWSTR newString = LocalAlloc(
  99. LMEM_FIXED,
  100. (lstrlenW(String) + 1) * sizeof(UNICODE_NULL)
  101. );
  102. if (newString != NULL) {
  103. lstrcpyW(newString, String);
  104. }
  105. return(newString);
  106. } // ClNetpCloneString
  107. BOOLEAN
  108. ClNetpIsNetworkNameUnique(
  109. IN LPWSTR NetworkName,
  110. IN PCLNET_CONFIG_LISTS ConfigLists,
  111. IN PLIST_ENTRY UnchangedConfigList
  112. )
  113. {
  114. PLIST_ENTRY listEntry;
  115. PCLNET_CONFIG_ENTRY configEntry;
  116. PLIST_ENTRY listHead;
  117. ClNetDbgPrint((
  118. LOG_NOISE,
  119. "[ClNet] Checking uniqueness of net name '%1!ws!'\n",
  120. NetworkName
  121. ));
  122. //
  123. // Check the existing cluster network definitions for a duplicate
  124. //
  125. listHead = &(ConfigLists->InputConfigList);
  126. for (;;) {
  127. for (listEntry = listHead->Flink;
  128. listEntry != listHead;
  129. listEntry = listEntry->Flink
  130. )
  131. {
  132. configEntry = CONTAINING_RECORD(
  133. listEntry,
  134. CLNET_CONFIG_ENTRY,
  135. Linkage
  136. );
  137. if (lstrcmpiW(NetworkName, configEntry->NetworkInfo.Name) == 0) {
  138. ClNetDbgPrint((
  139. LOG_NOISE,
  140. "[ClNet] Net name '%1!ws!' is not unique\n",
  141. NetworkName
  142. ));
  143. return(FALSE);
  144. }
  145. }
  146. if (listHead == &(ConfigLists->InputConfigList)) {
  147. listHead = &(ConfigLists->DeletedInterfaceList);
  148. }
  149. else if (listHead == &(ConfigLists->DeletedInterfaceList)) {
  150. listHead = &(ConfigLists->UpdatedInterfaceList);
  151. }
  152. else if (listHead == &(ConfigLists->UpdatedInterfaceList)) {
  153. listHead = &(ConfigLists->CreatedNetworkList);
  154. }
  155. else if (listHead == &(ConfigLists->CreatedNetworkList)) {
  156. listHead = UnchangedConfigList;
  157. }
  158. else {
  159. break;
  160. }
  161. }
  162. ClNetDbgPrint((
  163. LOG_NOISE,
  164. "[ClNet] Net name '%1!ws!' is unique\n",
  165. NetworkName
  166. ));
  167. return(TRUE);
  168. } // ClNetpIsNetworkNameUnique
  169. LPWSTR
  170. ClNetpMakeNetworkName(
  171. IN LPWSTR OldNetworkName,
  172. IN DWORD InstanceNumber
  173. )
  174. {
  175. LPWSTR newName, endPtr, truncatePtr, ptr;
  176. DWORD length, tempInstance, tempLength;
  177. ClNetDbgPrint((
  178. LOG_NOISE,
  179. "[ClNet] Attempt to make net name '%1!ws!' unique by appending (%2!u!)\n",
  180. OldNetworkName,
  181. InstanceNumber
  182. ));
  183. //
  184. // Append (InstanceNumber) to name string
  185. //
  186. for (endPtr = OldNetworkName, length = 0;
  187. *endPtr != UNICODE_NULL;
  188. endPtr++, length++
  189. );
  190. //
  191. // Check if there is already an instance number appended.
  192. //
  193. if ( (length > 3) && (*(endPtr - 1) == L')') ) {
  194. ClNetDbgPrint((
  195. LOG_NOISE,
  196. "[ClNet] There may already be an instance number appended to '%1!ws!'\n",
  197. OldNetworkName
  198. ));
  199. //
  200. // Scan backwards looking for '('
  201. //
  202. for (ptr = endPtr - 2, tempLength = 0;
  203. ptr != OldNetworkName;
  204. ptr--, tempLength++
  205. )
  206. {
  207. if (*ptr == L'(') {
  208. //
  209. // Looks promising. Check that all characters in between are
  210. // numbers and that the string size is reasonable.
  211. //
  212. if ((tempLength == 0) || (tempLength > 3)) {
  213. ClNetDbgPrint((
  214. LOG_NOISE,
  215. "[ClNet] Unsure net name %'1!ws!' contains an instance number - ignore.\n",
  216. OldNetworkName
  217. ));
  218. break;
  219. }
  220. truncatePtr = ptr;
  221. for (ptr++; *ptr != L')'; ptr++) {
  222. if ( (*ptr < L'0') || (*ptr > L'9') ) {
  223. ClNetDbgPrint((
  224. LOG_NOISE,
  225. "[ClNet] Tail of net name '%1!ws!' is not an instance number\n",
  226. OldNetworkName
  227. ));
  228. break;
  229. }
  230. }
  231. if (*ptr == L')') {
  232. //
  233. // This is an instance number. Truncate the string here.
  234. //
  235. ClNetDbgPrint((
  236. LOG_NOISE,
  237. "[ClNet] Replacing old instance number '%1!ws!' appended to name '%2!ws!'\n",
  238. truncatePtr,
  239. OldNetworkName
  240. ));
  241. *truncatePtr = UNICODE_NULL;
  242. length -= tempLength + 2;
  243. }
  244. break;
  245. }
  246. }
  247. }
  248. //
  249. // Count number of digits in instance number
  250. //
  251. for (tempInstance = InstanceNumber;
  252. tempInstance > 0;
  253. tempInstance /= 10, length++
  254. );
  255. //
  256. // Account for '(', ')', and NULL
  257. //
  258. length += 3;
  259. newName = LocalAlloc(LMEM_FIXED, length * sizeof(WCHAR));
  260. if (newName == NULL) {
  261. return(NULL);
  262. }
  263. wsprintfW(newName, L"%ws(%u)", OldNetworkName, InstanceNumber);
  264. ClNetDbgPrint((
  265. LOG_NOISE,
  266. "[ClNet] New net name is '%1!ws!'\n",
  267. newName
  268. ));
  269. return(newName);
  270. } // ClNetpMakeNetworkName
  271. LPWSTR
  272. ClNetpMakeUniqueNetworkName(
  273. IN LPWSTR ConnectoidName,
  274. IN LPWSTR ConnectoidGuid,
  275. IN PCLNET_CONFIG_LISTS ConfigLists,
  276. IN PLIST_ENTRY UnchangedConfigList
  277. )
  278. {
  279. BOOLEAN unique;
  280. BOOLEAN updateConnectoid = FALSE;
  281. LPWSTR newNetworkName;
  282. DWORD index = 1;
  283. newNetworkName = ClNetpCloneString(ConnectoidName);
  284. if (newNetworkName == NULL) {
  285. return(NULL);
  286. }
  287. do {
  288. unique = ClNetpIsNetworkNameUnique(
  289. newNetworkName,
  290. ConfigLists,
  291. UnchangedConfigList
  292. );
  293. if (!unique) {
  294. LPWSTR oldNetworkName = newNetworkName;
  295. newNetworkName = ClNetpMakeNetworkName(
  296. oldNetworkName,
  297. index++
  298. );
  299. LocalFree(oldNetworkName);
  300. if (newNetworkName == NULL) {
  301. return(NULL);
  302. }
  303. updateConnectoid = TRUE;
  304. }
  305. } while (!unique);
  306. //
  307. // Update the local connectoid name if necessary.
  308. //
  309. if (updateConnectoid) {
  310. DWORD status;
  311. ClNetDbgPrint((LOG_UNUSUAL,
  312. "[ClNet] Changing name of connectoid '%1!ws!' to '%2!ws!' to "
  313. "guarantee cluster-wide uniqueness\n",
  314. ConnectoidName,
  315. newNetworkName
  316. ));
  317. status = ClRtlFindConnectoidByGuidAndSetName(
  318. ConnectoidGuid,
  319. newNetworkName
  320. );
  321. if (status != ERROR_SUCCESS) {
  322. ClNetDbgPrint((LOG_UNUSUAL,
  323. "[ClNet] Failed to change name of connectoid '%1!ws!' to "
  324. "'%2!ws!', status %3!u!\n",
  325. ConnectoidName,
  326. newNetworkName,
  327. status
  328. ));
  329. }
  330. }
  331. return(newNetworkName);
  332. } // ClNetpMakeUniqueNetworkName
  333. DWORD
  334. ClNetpUpdateConfigEntry(
  335. PCLNET_CONFIG_ENTRY ConfigEntry,
  336. LPWSTR Address,
  337. LPWSTR AdapterId,
  338. LPWSTR AdapterName,
  339. LPWSTR NodeName,
  340. LPWSTR NetworkName
  341. )
  342. {
  343. LPWSTR newAddress = NULL;
  344. LPWSTR newInterfaceName = NULL;
  345. LPWSTR newAdapterId = NULL;
  346. LPWSTR newAdapterName = NULL;
  347. if (Address != NULL) {
  348. newAddress = ClNetpCloneString(Address);
  349. if (newAddress == NULL) {
  350. goto error_exit;
  351. }
  352. }
  353. if (AdapterId != NULL) {
  354. newAdapterId = ClNetpCloneString(AdapterId);
  355. if (newAdapterId == NULL) {
  356. goto error_exit;
  357. }
  358. }
  359. if (AdapterName != NULL) {
  360. newAdapterName = ClNetpCloneString(AdapterName);
  361. if (newAdapterName == NULL) {
  362. goto error_exit;
  363. }
  364. }
  365. if ( (NodeName != NULL) && (NetworkName != NULL) ) {
  366. newInterfaceName = ClNetMakeInterfaceName(
  367. NULL,
  368. NodeName,
  369. NetworkName
  370. );
  371. if (newInterfaceName == NULL) {
  372. goto error_exit;
  373. }
  374. }
  375. if (newAddress != NULL) {
  376. LocalFree(ConfigEntry->InterfaceInfo.Address);
  377. ConfigEntry->InterfaceInfo.Address = newAddress;
  378. }
  379. if (newAdapterId != NULL) {
  380. LocalFree(ConfigEntry->InterfaceInfo.AdapterId);
  381. ConfigEntry->InterfaceInfo.AdapterId = newAdapterId;
  382. }
  383. if (newAdapterName != NULL) {
  384. LocalFree(ConfigEntry->InterfaceInfo.AdapterName);
  385. ConfigEntry->InterfaceInfo.AdapterName = newAdapterName;
  386. }
  387. if (newInterfaceName != NULL) {
  388. LocalFree(ConfigEntry->InterfaceInfo.Name);
  389. ConfigEntry->InterfaceInfo.Name = newInterfaceName;
  390. }
  391. return(ERROR_SUCCESS);
  392. error_exit:
  393. if (newAddress != NULL) {
  394. LocalFree(newAddress);
  395. }
  396. if (newAdapterId != NULL) {
  397. LocalFree(newAdapterId);
  398. }
  399. if (newAdapterName != NULL) {
  400. LocalFree(newAdapterName);
  401. }
  402. if (newInterfaceName != NULL) {
  403. LocalFree(newInterfaceName);
  404. }
  405. return(ERROR_NOT_ENOUGH_MEMORY);
  406. } // ClNetpUpdateConfigEntry
  407. DWORD
  408. ClNetpAllocConfigEntryInterface(
  409. IN PCLNET_CONFIG_ENTRY ConfigEntry,
  410. IN LPWSTR InterfaceId,
  411. IN LPWSTR InterfaceName,
  412. IN LPWSTR InterfaceDescription,
  413. IN LPWSTR NodeId,
  414. IN LPWSTR AdapterId,
  415. IN LPWSTR AdapterName,
  416. IN LPWSTR InterfaceAddress,
  417. IN LPWSTR ClusnetEndpoint,
  418. IN DWORD InterfaceState
  419. )
  420. {
  421. PNM_INTERFACE_INFO2 interfaceInfo = &(ConfigEntry->InterfaceInfo);
  422. if (InterfaceId != NULL) {
  423. interfaceInfo->Id = ClNetpCloneString(InterfaceId);
  424. if (interfaceInfo->Id == NULL) {
  425. goto error_exit;
  426. }
  427. }
  428. ConfigEntry->IsInterfaceInfoValid = TRUE;
  429. if (InterfaceName != NULL) {
  430. interfaceInfo->Name = ClNetpCloneString(InterfaceName);
  431. if (interfaceInfo->Name == NULL) {
  432. goto error_exit;
  433. }
  434. }
  435. if (InterfaceDescription != NULL) {
  436. interfaceInfo->Description = ClNetpCloneString(InterfaceDescription);
  437. if (interfaceInfo->Description == NULL) {
  438. goto error_exit;
  439. }
  440. }
  441. if (NodeId != NULL) {
  442. interfaceInfo->NodeId = ClNetpCloneString(NodeId);
  443. if (interfaceInfo->NodeId == NULL) {
  444. goto error_exit;
  445. }
  446. }
  447. interfaceInfo->NetworkId = ClNetpCloneString(ConfigEntry->NetworkInfo.Id);
  448. if (interfaceInfo->NetworkId == NULL) {
  449. goto error_exit;
  450. }
  451. if (AdapterId != NULL) {
  452. interfaceInfo->AdapterId = ClNetpCloneString(AdapterId);
  453. if (interfaceInfo->AdapterId == NULL) {
  454. goto error_exit;
  455. }
  456. }
  457. if (AdapterName != NULL) {
  458. interfaceInfo->AdapterName = ClNetpCloneString(AdapterName);
  459. if (interfaceInfo->AdapterName == NULL) {
  460. goto error_exit;
  461. }
  462. }
  463. if (InterfaceAddress != NULL) {
  464. interfaceInfo->Address = ClNetpCloneString(InterfaceAddress);
  465. if (interfaceInfo->Address == NULL) {
  466. goto error_exit;
  467. }
  468. }
  469. if (ClusnetEndpoint != NULL) {
  470. interfaceInfo->ClusnetEndpoint = ClNetpCloneString(ClusnetEndpoint);
  471. if (interfaceInfo->ClusnetEndpoint == NULL) {
  472. goto error_exit;
  473. }
  474. }
  475. interfaceInfo->State = InterfaceState;
  476. interfaceInfo->NetIndex = NmInvalidInterfaceNetIndex;
  477. return(ERROR_SUCCESS);
  478. error_exit:
  479. ClNetFreeInterfaceInfo(&(ConfigEntry->InterfaceInfo));
  480. ConfigEntry->IsInterfaceInfoValid = FALSE;
  481. return(ERROR_NOT_ENOUGH_MEMORY);
  482. } // ClNetpAllocConfigEntryInterface
  483. DWORD
  484. ClNetpAllocConfigEntryNetwork(
  485. IN PCLNET_CONFIG_ENTRY ConfigEntry,
  486. IN LPWSTR NetworkId,
  487. IN LPWSTR NetworkName,
  488. IN LPWSTR NetworkDescription,
  489. IN DWORD NetworkRole,
  490. IN DWORD NetworkPriority,
  491. IN LPWSTR NetworkTransport,
  492. IN LPWSTR NetworkAddress,
  493. IN LPWSTR NetworkAddressMask
  494. )
  495. {
  496. PNM_NETWORK_INFO networkInfo;
  497. networkInfo = &(ConfigEntry->NetworkInfo);
  498. if (NetworkId != NULL) {
  499. networkInfo->Id = ClNetpCloneString(NetworkId);
  500. if (networkInfo->Id == NULL) {
  501. goto error_exit;
  502. }
  503. }
  504. if (NetworkName != NULL) {
  505. networkInfo->Name = ClNetpCloneString(NetworkName);
  506. if (networkInfo->Name == NULL) {
  507. goto error_exit;
  508. }
  509. }
  510. if (NetworkDescription != NULL) {
  511. networkInfo->Description = ClNetpCloneString(NetworkDescription);
  512. if (networkInfo->Description == NULL) {
  513. goto error_exit;
  514. }
  515. }
  516. networkInfo->Role = NetworkRole;
  517. networkInfo->Priority = NetworkPriority;
  518. if (NetworkTransport != NULL) {
  519. networkInfo->Transport = ClNetpCloneString(NetworkTransport);
  520. if (networkInfo->Transport == NULL) {
  521. goto error_exit;
  522. }
  523. }
  524. if (NetworkAddress != NULL) {
  525. networkInfo->Address = ClNetpCloneString(NetworkAddress);
  526. if (networkInfo->Address == NULL) {
  527. goto error_exit;
  528. }
  529. }
  530. if (NetworkAddressMask != NULL) {
  531. networkInfo->AddressMask = ClNetpCloneString(NetworkAddressMask);
  532. if (networkInfo->AddressMask == NULL) {
  533. goto error_exit;
  534. }
  535. }
  536. return(ERROR_SUCCESS);
  537. error_exit:
  538. ClNetFreeConfigEntry(ConfigEntry);
  539. return(ERROR_NOT_ENOUGH_MEMORY);
  540. } // ClNetpAllocConfigEntryNetwork
  541. DWORD
  542. ClNetpCreateConfigEntryInterface(
  543. PCLNET_CONFIG_ENTRY ConfigEntry,
  544. LPWSTR NodeName,
  545. LPWSTR NodeId,
  546. PCLRTL_NET_ADAPTER_INFO AdapterInfo,
  547. PCLRTL_NET_INTERFACE_INFO AdapterIfInfo,
  548. LPWSTR ClusnetEndpoint
  549. )
  550. {
  551. LPWSTR id;
  552. LPWSTR name;
  553. DWORD status = ERROR_NOT_ENOUGH_MEMORY;
  554. id = ClRtlMakeGuid();
  555. if (id != NULL) {
  556. name = ClNetMakeInterfaceName(
  557. NULL,
  558. NodeName,
  559. ConfigEntry->NetworkInfo.Name
  560. );
  561. if (name != NULL) {
  562. status = ClNetpAllocConfigEntryInterface(
  563. ConfigEntry,
  564. NULL, // Id
  565. NULL, // Name
  566. ClNetpEmptyString, // Description
  567. NodeId,
  568. AdapterInfo->DeviceGuid,
  569. AdapterInfo->DeviceName,
  570. AdapterIfInfo->InterfaceAddressString,
  571. ClusnetEndpoint,
  572. ClusterNetInterfaceUnavailable
  573. );
  574. if (status == ERROR_SUCCESS) {
  575. ConfigEntry->InterfaceInfo.Id = id;
  576. ConfigEntry->InterfaceInfo.Name = name;
  577. return(ERROR_SUCCESS);
  578. }
  579. LocalFree(name);
  580. }
  581. LocalFree(id);
  582. }
  583. return(status);
  584. } // ClNetpCreateInterface
  585. PCLNET_CONFIG_ENTRY
  586. ClNetpCreateConfigEntry(
  587. LPWSTR NodeName,
  588. LPWSTR NodeId,
  589. LPWSTR NetworkName,
  590. DWORD NetworkRole,
  591. DWORD NetworkPriority,
  592. PCLRTL_NET_ADAPTER_INFO AdapterInfo,
  593. PCLRTL_NET_INTERFACE_INFO AdapterIfInfo,
  594. LPWSTR ClusnetEndpoint
  595. )
  596. {
  597. PCLNET_CONFIG_ENTRY newEntry;
  598. DWORD status;
  599. newEntry = LocalAlloc(
  600. (LMEM_FIXED | LMEM_ZEROINIT),
  601. sizeof(CLNET_CONFIG_ENTRY)
  602. );
  603. if (newEntry == NULL) {
  604. return(NULL);
  605. }
  606. newEntry->NetworkInfo.Id = ClRtlMakeGuid();
  607. if (newEntry->NetworkInfo.Id == NULL) {
  608. goto error_exit;
  609. }
  610. newEntry->NetworkInfo.Name = ClNetpCloneString(NetworkName);
  611. if (newEntry->NetworkInfo.Name == NULL) {
  612. goto error_exit;
  613. }
  614. status = ClNetpCreateConfigEntryInterface(
  615. newEntry,
  616. NodeName,
  617. NodeId,
  618. AdapterInfo,
  619. AdapterIfInfo,
  620. ClusnetEndpoint
  621. );
  622. if (status != ERROR_SUCCESS) {
  623. goto error_exit;
  624. }
  625. status = ClNetpAllocConfigEntryNetwork(
  626. newEntry,
  627. NULL, // NetworkId
  628. NULL, // NetworkName
  629. ClNetpEmptyString, // Description
  630. NetworkRole,
  631. NetworkPriority,
  632. L"Tcpip",
  633. AdapterIfInfo->NetworkAddressString,
  634. AdapterIfInfo->NetworkMaskString
  635. );
  636. if (status == ERROR_SUCCESS) {
  637. return(newEntry);
  638. }
  639. error_exit:
  640. ClNetFreeConfigEntry(newEntry);
  641. LocalFree(newEntry);
  642. return(NULL);
  643. } // ClNetpCreateConfigEntry
  644. DWORD
  645. ClNetpCopyNetworkInfo(
  646. IN PNM_NETWORK_INFO DstInfo,
  647. IN PNM_NETWORK_INFO SrcInfo
  648. )
  649. {
  650. DWORD status = ERROR_SUCCESS;
  651. try {
  652. DstInfo->Id = ClNetCopyString(SrcInfo->Id, TRUE);
  653. DstInfo->Name = ClNetCopyString(SrcInfo->Name, TRUE);
  654. DstInfo->Description = ClNetCopyString(SrcInfo->Description, TRUE);
  655. DstInfo->Role = SrcInfo->Role;
  656. DstInfo->Priority = SrcInfo->Priority;
  657. DstInfo->Transport = ClNetCopyString(SrcInfo->Transport, TRUE);
  658. DstInfo->Address = ClNetCopyString(SrcInfo->Address, TRUE);
  659. DstInfo->AddressMask = ClNetCopyString(SrcInfo->AddressMask, TRUE);
  660. DstInfo->Ignore = FALSE;
  661. } except (EXCEPTION_EXECUTE_HANDLER) {
  662. status = GetExceptionCode();
  663. ClNetFreeNetworkInfo(DstInfo);
  664. }
  665. return(status);
  666. } // ClNetpCopyNetworkInfo
  667. DWORD
  668. ClNetpCopyInterfaceInfo(
  669. IN PNM_INTERFACE_INFO2 DstInfo,
  670. IN PNM_INTERFACE_INFO2 SrcInfo
  671. )
  672. {
  673. DWORD status = ERROR_SUCCESS;
  674. try {
  675. DstInfo->Id = ClNetCopyString(SrcInfo->Id, TRUE);
  676. DstInfo->Name = ClNetCopyString(SrcInfo->Name, TRUE);
  677. DstInfo->Description = ClNetCopyString(SrcInfo->Description, TRUE);
  678. DstInfo->NodeId = ClNetCopyString(SrcInfo->NodeId, TRUE);
  679. DstInfo->NetworkId = ClNetCopyString(SrcInfo->NetworkId, TRUE);
  680. DstInfo->AdapterName = ClNetCopyString(SrcInfo->AdapterName, TRUE);
  681. DstInfo->Address = ClNetCopyString(SrcInfo->Address, TRUE);
  682. DstInfo->ClusnetEndpoint = ClNetCopyString(
  683. SrcInfo->ClusnetEndpoint,
  684. TRUE
  685. );
  686. DstInfo->State = SrcInfo->State;
  687. DstInfo->Ignore = FALSE;
  688. DstInfo->AdapterId = ClNetCopyString(SrcInfo->AdapterId, TRUE);
  689. DstInfo->NetIndex = SrcInfo->NetIndex;
  690. } except (EXCEPTION_EXECUTE_HANDLER) {
  691. status = GetExceptionCode();
  692. ClNetFreeInterfaceInfo(DstInfo);
  693. }
  694. return(status);
  695. } // ClNetpCopyInterfaceInfo
  696. //////////////////////////////////////////////////////////////////////////////
  697. //
  698. // Public routines
  699. //
  700. //////////////////////////////////////////////////////////////////////////////
  701. VOID
  702. ClNetInitialize(
  703. IN LPFN_CLNETPRINT pfnPrint,
  704. IN LPFN_CLNETLOGEVENT pfnLogEvent,
  705. IN LPFN_CLNETLOGEVENT1 pfnLogEvent1,
  706. IN LPFN_CLNETLOGEVENT2 pfnLogEvent2,
  707. IN LPFN_CLNETLOGEVENT3 pfnLogEvent3
  708. )
  709. {
  710. pClNetPrint = pfnPrint;
  711. pClNetLogEvent = pfnLogEvent;
  712. pClNetLogEvent1 = pfnLogEvent1;
  713. pClNetLogEvent2 = pfnLogEvent2;
  714. pClNetLogEvent3 = pfnLogEvent3;
  715. } // ClNetInitialize
  716. LPWSTR
  717. ClNetCopyString(
  718. IN LPWSTR SourceString,
  719. IN BOOL RaiseExceptionOnError
  720. )
  721. {
  722. LPWSTR str;
  723. str = (LPWSTR) MIDL_user_allocate(
  724. (lstrlenW(SourceString) + 1) * sizeof(WCHAR)
  725. );
  726. if (str != NULL) {
  727. lstrcpyW(str, SourceString);
  728. }
  729. else if (RaiseExceptionOnError) {
  730. RaiseException(ERROR_NOT_ENOUGH_MEMORY, 0, 0, NULL);
  731. }
  732. return(str);
  733. } // ClNetCopyString
  734. VOID
  735. ClNetInitializeConfigLists(
  736. PCLNET_CONFIG_LISTS Lists
  737. )
  738. {
  739. InitializeListHead(&(Lists->InputConfigList));
  740. InitializeListHead(&(Lists->DeletedInterfaceList));
  741. InitializeListHead(&(Lists->UpdatedInterfaceList));
  742. InitializeListHead(&(Lists->CreatedInterfaceList));
  743. InitializeListHead(&(Lists->CreatedNetworkList));
  744. return;
  745. } // ClNetInitializeConfigLists
  746. DWORD
  747. ClNetConvertEnumsToConfigList(
  748. IN PNM_NETWORK_ENUM * NetworkEnum,
  749. IN PNM_INTERFACE_ENUM2 * InterfaceEnum,
  750. IN LPWSTR LocalNodeId,
  751. IN OUT PLIST_ENTRY ConfigList,
  752. IN BOOLEAN DeleteEnums
  753. )
  754. {
  755. DWORD i, j;
  756. DWORD status;
  757. PNM_NETWORK_INFO network;
  758. PNM_INTERFACE_INFO2 netInterface;
  759. PCLNET_CONFIG_ENTRY configEntry;
  760. InitializeListHead(ConfigList);
  761. for (i=0; i<(*NetworkEnum)->NetworkCount; i++) {
  762. network = &((*NetworkEnum)->NetworkList[i]);
  763. configEntry = LocalAlloc(
  764. (LMEM_FIXED | LMEM_ZEROINIT),
  765. sizeof(CLNET_CONFIG_ENTRY)
  766. );
  767. if (configEntry == NULL) {
  768. status = ERROR_NOT_ENOUGH_MEMORY;
  769. goto error_exit;
  770. }
  771. if (DeleteEnums) {
  772. CopyMemory(
  773. &(configEntry->NetworkInfo),
  774. network,
  775. sizeof(NM_NETWORK_INFO)
  776. );
  777. }
  778. else {
  779. status = ClNetpCopyNetworkInfo(
  780. &(configEntry->NetworkInfo),
  781. network
  782. );
  783. if (status != ERROR_SUCCESS) {
  784. goto error_exit;
  785. }
  786. }
  787. for (j=0; j<(*InterfaceEnum)->InterfaceCount; j++) {
  788. netInterface = &((*InterfaceEnum)->InterfaceList[j]);
  789. if ( (netInterface->Ignore == FALSE) &&
  790. (lstrcmpiW(netInterface->NetworkId, network->Id) == 0) &&
  791. (lstrcmpiW(netInterface->NodeId, LocalNodeId) == 0)
  792. )
  793. {
  794. if (DeleteEnums) {
  795. CopyMemory(
  796. &(configEntry->InterfaceInfo),
  797. netInterface,
  798. sizeof(NM_INTERFACE_INFO2)
  799. );
  800. }
  801. else {
  802. status = ClNetpCopyInterfaceInfo(
  803. &(configEntry->InterfaceInfo),
  804. netInterface
  805. );
  806. if (status != ERROR_SUCCESS) {
  807. goto error_exit;
  808. }
  809. }
  810. configEntry->IsInterfaceInfoValid = TRUE;
  811. if ( DeleteEnums ) {
  812. ZeroMemory(netInterface, sizeof(NM_INTERFACE_INFO2));
  813. }
  814. netInterface->Ignore = TRUE;
  815. break;
  816. }
  817. }
  818. InsertTailList(ConfigList, &(configEntry->Linkage));
  819. if ( DeleteEnums ) {
  820. ZeroMemory(network, sizeof(NM_NETWORK_INFO));
  821. }
  822. }
  823. status = ERROR_SUCCESS;
  824. error_exit:
  825. if ( DeleteEnums ) {
  826. ClNetFreeNetworkEnum(*NetworkEnum); *NetworkEnum = NULL;
  827. ClNetFreeInterfaceEnum(*InterfaceEnum); *InterfaceEnum = NULL;
  828. }
  829. if (status != ERROR_SUCCESS) {
  830. ClNetFreeConfigList(ConfigList);
  831. }
  832. return(status);
  833. } // ClNetConvertEnumsToConfigList
  834. VOID
  835. ClNetFreeNetworkEnum(
  836. IN PNM_NETWORK_ENUM NetworkEnum
  837. )
  838. /*++
  839. Routine Description:
  840. Frees a network enumeration structure.
  841. Arguments:
  842. NetworkEnum - A pointer to the network enumeration structure to free.
  843. Return Value:
  844. None.
  845. --*/
  846. {
  847. DWORD i;
  848. for (i=0; i<NetworkEnum->NetworkCount; i++) {
  849. ClNetFreeNetworkInfo(&(NetworkEnum->NetworkList[i]));
  850. }
  851. MIDL_user_free(NetworkEnum);
  852. return;
  853. } // ClNetFreeNetworkEnum
  854. VOID
  855. ClNetFreeNetworkInfo(
  856. IN PNM_NETWORK_INFO NetworkInfo
  857. )
  858. /*++
  859. Routine Description:
  860. Frees a network information structure or a linked list of network
  861. information structures.
  862. Arguments:
  863. NetworkInfo - A pointer to the network information structure
  864. to free.
  865. Return Value:
  866. None.
  867. --*/
  868. {
  869. if (NetworkInfo->Id != NULL) {
  870. MIDL_user_free(NetworkInfo->Id);
  871. NetworkInfo->Id = NULL;
  872. }
  873. if (NetworkInfo->Name != NULL) {
  874. MIDL_user_free(NetworkInfo->Name);
  875. NetworkInfo->Name = NULL;
  876. }
  877. if (NetworkInfo->Description != NULL) {
  878. MIDL_user_free(NetworkInfo->Description);
  879. NetworkInfo->Description = NULL;
  880. }
  881. if (NetworkInfo->Transport != NULL) {
  882. MIDL_user_free(NetworkInfo->Transport);
  883. NetworkInfo->Transport = NULL;
  884. }
  885. if (NetworkInfo->Address != NULL) {
  886. MIDL_user_free(NetworkInfo->Address);
  887. NetworkInfo->Address = NULL;
  888. }
  889. if (NetworkInfo->AddressMask != NULL) {
  890. MIDL_user_free(NetworkInfo->AddressMask);
  891. NetworkInfo->AddressMask = NULL;
  892. }
  893. return;
  894. } // ClNetFreeNetworkInfo
  895. VOID
  896. ClNetFreeInterfaceEnum1(
  897. IN PNM_INTERFACE_ENUM InterfaceEnum1
  898. )
  899. /*++
  900. Routine Description:
  901. Frees a interface enumeration structure.
  902. Arguments:
  903. InterfaceEnum - A pointer to the interface enumeration structure
  904. to free.
  905. Return Value:
  906. None.
  907. --*/
  908. {
  909. DWORD i;
  910. for (i=0; i<InterfaceEnum1->InterfaceCount; i++) {
  911. ClNetFreeInterfaceInfo(
  912. (PNM_INTERFACE_INFO2) &(InterfaceEnum1->InterfaceList[i])
  913. );
  914. }
  915. MIDL_user_free(InterfaceEnum1);
  916. return;
  917. } // ClNetFreeInterfaceEnum
  918. VOID
  919. ClNetFreeInterfaceEnum(
  920. IN PNM_INTERFACE_ENUM2 InterfaceEnum
  921. )
  922. /*++
  923. Routine Description:
  924. Frees a interface enumeration structure.
  925. Arguments:
  926. InterfaceEnum - A pointer to the interface enumeration structure
  927. to free.
  928. Return Value:
  929. None.
  930. --*/
  931. {
  932. DWORD i;
  933. for (i=0; i<InterfaceEnum->InterfaceCount; i++) {
  934. ClNetFreeInterfaceInfo(&(InterfaceEnum->InterfaceList[i]));
  935. }
  936. MIDL_user_free(InterfaceEnum);
  937. return;
  938. } // ClNetFreeInterfaceEnum
  939. VOID
  940. ClNetFreeInterfaceInfo(
  941. IN PNM_INTERFACE_INFO2 InterfaceInfo
  942. )
  943. /*++
  944. Routine Description:
  945. Frees a network interface information strucuture.
  946. Arguments:
  947. InterfaceInfo - A pointer to the interface information
  948. structure to free.
  949. Return Value:
  950. None.
  951. --*/
  952. {
  953. if (InterfaceInfo->Id != NULL) {
  954. MIDL_user_free(InterfaceInfo->Id);
  955. InterfaceInfo->Id = NULL;
  956. }
  957. if (InterfaceInfo->Name != NULL) {
  958. MIDL_user_free(InterfaceInfo->Name);
  959. InterfaceInfo->Name = NULL;
  960. }
  961. if (InterfaceInfo->Description != NULL) {
  962. MIDL_user_free(InterfaceInfo->Description);
  963. InterfaceInfo->Description = NULL;
  964. }
  965. if (InterfaceInfo->NetworkId != NULL) {
  966. MIDL_user_free(InterfaceInfo->NetworkId);
  967. InterfaceInfo->NetworkId = NULL;
  968. }
  969. if (InterfaceInfo->NodeId != NULL) {
  970. MIDL_user_free(InterfaceInfo->NodeId);
  971. InterfaceInfo->NodeId = NULL;
  972. }
  973. if (InterfaceInfo->AdapterId != NULL) {
  974. MIDL_user_free(InterfaceInfo->AdapterId);
  975. InterfaceInfo->AdapterId = NULL;
  976. }
  977. if (InterfaceInfo->AdapterName != NULL) {
  978. MIDL_user_free(InterfaceInfo->AdapterName);
  979. InterfaceInfo->AdapterName = NULL;
  980. }
  981. if (InterfaceInfo->Address != NULL) {
  982. MIDL_user_free(InterfaceInfo->Address);
  983. InterfaceInfo->Address = NULL;
  984. }
  985. if (InterfaceInfo->ClusnetEndpoint != NULL) {
  986. MIDL_user_free(InterfaceInfo->ClusnetEndpoint);
  987. InterfaceInfo->ClusnetEndpoint = NULL;
  988. }
  989. return;
  990. } // ClNetFreeInterfaceInfo
  991. VOID
  992. ClNetFreeNodeEnum1(
  993. IN PNM_NODE_ENUM NodeEnum1
  994. )
  995. /*++
  996. Routine Description:
  997. Frees a node enumeration structure.
  998. Arguments:
  999. NodeEnum - A pointer to the node enumeration structure to free.
  1000. Return Value:
  1001. None.
  1002. --*/
  1003. {
  1004. DWORD i;
  1005. for (i=0; i<NodeEnum1->NodeCount; i++) {
  1006. ClNetFreeNodeInfo(
  1007. (PNM_NODE_INFO2) &(NodeEnum1->NodeList[i])
  1008. );
  1009. }
  1010. MIDL_user_free(NodeEnum1);
  1011. return;
  1012. } // NmpFreeNodeEnum1
  1013. VOID
  1014. ClNetFreeNodeEnum(
  1015. IN PNM_NODE_ENUM2 NodeEnum
  1016. )
  1017. /*++
  1018. Routine Description:
  1019. Frees a node enumeration structure.
  1020. Arguments:
  1021. NodeEnum - A pointer to the node enumeration structure to free.
  1022. Return Value:
  1023. None.
  1024. --*/
  1025. {
  1026. DWORD i;
  1027. for (i=0; i<NodeEnum->NodeCount; i++) {
  1028. ClNetFreeNodeInfo(&(NodeEnum->NodeList[i]));
  1029. }
  1030. MIDL_user_free(NodeEnum);
  1031. return;
  1032. } // NmpFreeNodeEnum
  1033. VOID
  1034. ClNetFreeNodeInfo(
  1035. IN PNM_NODE_INFO2 NodeInfo
  1036. )
  1037. /*++
  1038. Routine Description:
  1039. Frees a node information structure.
  1040. Arguments:
  1041. NodeInfo - A pointer to the node information structure to free.
  1042. Return Value:
  1043. None.
  1044. --*/
  1045. {
  1046. //
  1047. // Currently nothing to free.
  1048. //
  1049. return;
  1050. } // NmpFreeNodeInfo
  1051. VOID
  1052. ClNetFreeConfigEntry(
  1053. PCLNET_CONFIG_ENTRY ConfigEntry
  1054. )
  1055. {
  1056. ClNetFreeNetworkInfo(&(ConfigEntry->NetworkInfo));
  1057. if (ConfigEntry->IsInterfaceInfoValid) {
  1058. ClNetFreeInterfaceInfo(&(ConfigEntry->InterfaceInfo));
  1059. }
  1060. return;
  1061. } // ClNetFreeConfigEntry
  1062. VOID
  1063. ClNetFreeConfigList(
  1064. IN PLIST_ENTRY ConfigList
  1065. )
  1066. {
  1067. PLIST_ENTRY listEntry;
  1068. PCLNET_CONFIG_ENTRY configEntry;
  1069. while (!IsListEmpty(ConfigList)) {
  1070. listEntry = RemoveHeadList(ConfigList);
  1071. configEntry = CONTAINING_RECORD(
  1072. listEntry,
  1073. CLNET_CONFIG_ENTRY,
  1074. Linkage
  1075. );
  1076. ClNetFreeConfigEntry(configEntry);
  1077. }
  1078. return;
  1079. } // ClNetFreeConfigList
  1080. VOID
  1081. ClNetFreeConfigLists(
  1082. PCLNET_CONFIG_LISTS ConfigLists
  1083. )
  1084. {
  1085. ClNetFreeConfigList(&(ConfigLists->InputConfigList));
  1086. ClNetFreeConfigList(&(ConfigLists->DeletedInterfaceList));
  1087. ClNetFreeConfigList(&(ConfigLists->UpdatedInterfaceList));
  1088. ClNetFreeConfigList(&(ConfigLists->CreatedInterfaceList));
  1089. ClNetFreeConfigList(&(ConfigLists->CreatedNetworkList));
  1090. return;
  1091. } // ClNetFreeConfigLists
  1092. LPWSTR
  1093. ClNetMakeInterfaceName(
  1094. LPWSTR Prefix, OPTIONAL
  1095. LPWSTR NodeName,
  1096. LPWSTR NetworkName
  1097. )
  1098. /*++
  1099. Construct a name of the form "<network name> - <node name>".
  1100. Code in cluscfg.exe depends on this form. If you change this,
  1101. you need to change the code in setup\cluscfg\netadptr.cpp as
  1102. well
  1103. --*/
  1104. {
  1105. WCHAR text[] = L" - ";
  1106. LPWSTR name;
  1107. DWORD nameLength = 0;
  1108. if (Prefix != NULL) {
  1109. nameLength += lstrlenW(Prefix);
  1110. }
  1111. nameLength += lstrlenW(text) + lstrlenW(NodeName) +
  1112. lstrlenW(NetworkName) + 1;
  1113. nameLength *= sizeof(WCHAR);
  1114. name = MIDL_user_allocate(nameLength);
  1115. if (name != NULL) {
  1116. name[0] = UNICODE_NULL;
  1117. if (Prefix != NULL) {
  1118. lstrcatW(name, Prefix);
  1119. }
  1120. lstrcatW(name, NetworkName);
  1121. lstrcatW(name, text);
  1122. lstrcatW(name, NodeName);
  1123. return(name);
  1124. }
  1125. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  1126. return(NULL);
  1127. } // ClNetMakeInterfaceName
  1128. DWORD
  1129. ClNetConfigureNetworks(
  1130. IN LPWSTR LocalNodeId,
  1131. IN LPWSTR LocalNodeName,
  1132. IN LPWSTR DefaultClusnetEndpoint,
  1133. IN CLUSTER_NETWORK_ROLE DefaultNetworkRole,
  1134. IN BOOL NetNameHasPrecedence,
  1135. IN OUT PCLNET_CONFIG_LISTS ConfigLists,
  1136. IN OUT LPDWORD MatchedNetworkCount,
  1137. IN OUT LPDWORD NewNetworkCount
  1138. )
  1139. /*++
  1140. Notes:
  1141. NetNameHasPrecedence is TRUE if connectoid names should be changed to
  1142. align with the name in the NM_NETWORK_INFO struct. Otherwise the name of
  1143. network object is changed to match the connectoid name.
  1144. Output interface lists must be processed in the following order to
  1145. guarantee correctness:
  1146. 1 - DeletedInterfaceList
  1147. 2 - UpdatedInterfaceList
  1148. 3 - CreatedInterfaceList
  1149. 4 - CreatedNetworkList
  1150. --*/
  1151. {
  1152. DWORD status = ERROR_SUCCESS;
  1153. PCLRTL_NET_ADAPTER_ENUM adapterEnum = NULL;
  1154. PCLRTL_NET_ADAPTER_INFO adapterInfo = NULL;
  1155. PCLRTL_NET_INTERFACE_INFO adapterIfInfo = NULL;
  1156. WCHAR errorString[12];
  1157. DWORD eventCode = 0;
  1158. DWORD hiddenAdapterCount = 0;
  1159. PLIST_ENTRY listEntry;
  1160. PCLNET_CONFIG_ENTRY configEntry;
  1161. PNM_NETWORK_INFO networkInfo;
  1162. PNM_INTERFACE_INFO2 interfaceInfo;
  1163. LIST_ENTRY unchangedConfigList;
  1164. DWORD matchedNetworkCount = 0;
  1165. DWORD newNetworkCount = 0;
  1166. BOOLEAN newAdapter;
  1167. ClNetDbgPrint((LOG_NOISE, "[ClNet] Configuring networks...\n"));
  1168. if (NetNameHasPrecedence) {
  1169. ClNetDbgPrint((
  1170. LOG_NOISE,
  1171. "[ClNet] Cluster network names have precedence over "
  1172. "local connection object names.\n"
  1173. ));
  1174. }
  1175. else {
  1176. ClNetDbgPrint((
  1177. LOG_NOISE,
  1178. "[ClNet] Local connection object names have precedence "
  1179. "over cluster network names.\n"
  1180. ));
  1181. }
  1182. InitializeListHead(&unchangedConfigList);
  1183. //
  1184. // Obtain the network configuration for the local system.
  1185. //
  1186. ClNetDbgPrint((
  1187. LOG_NOISE,
  1188. "[ClNet] Querying local network configuration.\n"
  1189. ));
  1190. adapterEnum = ClRtlEnumNetAdapters();
  1191. if (adapterEnum == NULL) {
  1192. status = GetLastError();
  1193. wsprintfW(&(errorString[0]), L"%u", status);
  1194. (*pClNetLogEvent1)(
  1195. LOG_CRITICAL,
  1196. CLNET_EVENT_QUERY_CONFIG_FAILED,
  1197. errorString
  1198. );
  1199. ClNetDbgPrint((
  1200. LOG_CRITICAL,
  1201. "[ClNet] Failed to obtain local system network config, "
  1202. "status %1!u!.\n",
  1203. status
  1204. ));
  1205. return(status);
  1206. }
  1207. //
  1208. // Ignore all adapters which are hidden or have an address of 0.0.0.0.
  1209. //
  1210. for (adapterInfo = adapterEnum->AdapterList;
  1211. adapterInfo != NULL;
  1212. adapterInfo = adapterInfo->Next
  1213. )
  1214. {
  1215. if (adapterInfo->Flags & CLRTL_NET_ADAPTER_HIDDEN) {
  1216. ClNetDbgPrint((
  1217. LOG_NOISE,
  1218. "[ClNet] Ignoring hidden adapter '%1!ws!' (%2!ws!).\n",
  1219. adapterInfo->DeviceName,
  1220. adapterInfo->DeviceGuid
  1221. ));
  1222. adapterInfo->Ignore = TRUE;
  1223. hiddenAdapterCount++;
  1224. }
  1225. else {
  1226. adapterIfInfo = ClRtlGetPrimaryNetInterface(adapterInfo);
  1227. if (adapterIfInfo != NULL) {
  1228. if (adapterIfInfo->InterfaceAddress == 0) {
  1229. (*pClNetLogEvent1)(
  1230. LOG_UNUSUAL,
  1231. CLNET_EVENT_INVALID_ADAPTER_ADDRESS,
  1232. adapterInfo->DeviceName
  1233. );
  1234. ClNetDbgPrint((
  1235. LOG_NOISE,
  1236. "[ClNet] Ignoring adapter '%1!ws!' "
  1237. "(%2!ws!) because its"
  1238. "primary address is 0.0.0.0.\n",
  1239. adapterInfo->DeviceName,
  1240. adapterInfo->DeviceGuid
  1241. ));
  1242. adapterInfo->Ignore = TRUE;
  1243. hiddenAdapterCount++;
  1244. }
  1245. }
  1246. else {
  1247. ClNetDbgPrint((
  1248. LOG_NOISE,
  1249. "[ClNet] Ignoring adapter '%1!ws!' "
  1250. "(%2!ws!) because its primary net "
  1251. "interface could not be found.\n",
  1252. adapterInfo->DeviceName,
  1253. adapterInfo->DeviceGuid
  1254. ));
  1255. adapterInfo->Ignore = TRUE;
  1256. hiddenAdapterCount++;
  1257. }
  1258. }
  1259. }
  1260. if ((adapterEnum->AdapterCount - hiddenAdapterCount) == 0) {
  1261. (*pClNetLogEvent)(
  1262. LOG_UNUSUAL,
  1263. CLNET_EVENT_NO_VALID_ADAPTER
  1264. );
  1265. ClNetDbgPrint((
  1266. LOG_CRITICAL,
  1267. "[ClNet] No usable network adapters are installed in this "
  1268. "system.\n"
  1269. ));
  1270. }
  1271. //
  1272. // Phase 1
  1273. //
  1274. // Validate existing interface definitions for this node
  1275. // and update as needed.
  1276. //
  1277. ClNetDbgPrint((
  1278. LOG_NOISE,
  1279. "[ClNet] Phase 1 - Examining previous network definitions.\n"
  1280. ));
  1281. //
  1282. // Walk all of the network definitions and examine the corresponding
  1283. // interface definitions for this node.
  1284. //
  1285. while (!IsListEmpty(&(ConfigLists->InputConfigList))) {
  1286. configEntry = CONTAINING_RECORD(
  1287. ConfigLists->InputConfigList.Flink,
  1288. CLNET_CONFIG_ENTRY,
  1289. Linkage
  1290. );
  1291. networkInfo = &(configEntry->NetworkInfo);
  1292. ClNetDbgPrint((
  1293. LOG_NOISE,
  1294. "[ClNet] Examining cluster network '%1!ws!' (%2!ws!).\n",
  1295. networkInfo->Name,
  1296. networkInfo->Id
  1297. ));
  1298. //
  1299. // Check if there is an existing interface definition for
  1300. // this node on this network.
  1301. //
  1302. if (configEntry->IsInterfaceInfoValid) {
  1303. // An interface definition already exists for this node on
  1304. // the network. We will either find an installed adapter for it
  1305. // or delete the interface.
  1306. //
  1307. interfaceInfo = &(configEntry->InterfaceInfo);
  1308. ClNetDbgPrint((
  1309. LOG_NOISE,
  1310. "[ClNet] This node was attached to the network by "
  1311. "adapter '%1!ws!', (%2!ws!).\n",
  1312. interfaceInfo->AdapterName,
  1313. interfaceInfo->AdapterId
  1314. ));
  1315. //
  1316. // Try to find the adapter specified in the interface
  1317. // definition. If it is still attached to the network,
  1318. // then we want to reuse it.
  1319. //
  1320. ClNetDbgPrint((
  1321. LOG_NOISE,
  1322. "[ClNet] Checking if adapter '%1!ws!' is still installed.\n",
  1323. interfaceInfo->AdapterName
  1324. ));
  1325. adapterInfo = ClRtlFindNetAdapterById(
  1326. adapterEnum,
  1327. interfaceInfo->AdapterId
  1328. );
  1329. if (adapterInfo != NULL) {
  1330. //
  1331. // Found the specified adapter. Check if this
  1332. // adapter is still attached to the network by
  1333. // comparing network address values.
  1334. //
  1335. ClNetDbgPrint((
  1336. LOG_NOISE,
  1337. "[ClNet] Adapter '%1!ws!' is still installed, checking "
  1338. "if it is still attached to the same network.\n",
  1339. adapterInfo->DeviceName
  1340. ));
  1341. adapterIfInfo = ClRtlFindNetInterfaceByNetworkAddress(
  1342. adapterInfo,
  1343. networkInfo->Address
  1344. );
  1345. if (adapterIfInfo != NULL) {
  1346. //
  1347. // The adapter is still attached to this network.
  1348. //
  1349. newAdapter = FALSE;
  1350. ClNetDbgPrint((
  1351. LOG_NOISE,
  1352. "[ClNet] Adapter '%1!ws!' is still attached to "
  1353. "network %2!ws!.\n",
  1354. interfaceInfo->AdapterName,
  1355. networkInfo->Name
  1356. ));
  1357. }
  1358. else {
  1359. //
  1360. // The adapter is no longer attached to this network.
  1361. //
  1362. adapterInfo = NULL;
  1363. ClNetDbgPrint((
  1364. LOG_NOISE,
  1365. "[ClNet] Adapter '%1!ws!' is no longer attached "
  1366. "to network %2!ws!.\n",
  1367. interfaceInfo->AdapterName,
  1368. networkInfo->Name
  1369. ));
  1370. }
  1371. }
  1372. else {
  1373. ClNetDbgPrint((
  1374. LOG_NOISE,
  1375. "[ClNet] Adapter '%1!ws!' is no longer available.\n",
  1376. interfaceInfo->AdapterName
  1377. ));
  1378. }
  1379. //
  1380. // If the old adapter was removed or is now attached to a
  1381. // different network, search for a new adapter that is
  1382. // attached to the network.
  1383. //
  1384. if (adapterInfo == NULL) {
  1385. ClNetDbgPrint((
  1386. LOG_NOISE,
  1387. "[ClNet] Searching for a new adapter which is attached "
  1388. "to network '%1!ws!'.\n",
  1389. networkInfo->Name
  1390. ));
  1391. adapterIfInfo = NULL;
  1392. adapterInfo = ClRtlFindNetAdapterByNetworkAddress(
  1393. adapterEnum,
  1394. networkInfo->Address,
  1395. &adapterIfInfo
  1396. );
  1397. if (adapterInfo != NULL) {
  1398. ClNetDbgPrint((
  1399. LOG_NOISE,
  1400. "[ClNet] Adapter '%1!ws!' (%2!ws!) is attached to "
  1401. "network '%3!ws!'.\n",
  1402. interfaceInfo->AdapterName,
  1403. interfaceInfo->AdapterId,
  1404. networkInfo->Name
  1405. ));
  1406. newAdapter = TRUE;
  1407. }
  1408. }
  1409. //
  1410. // If we found an adapter, old or new, which is attached to this
  1411. // network, update the interface definition, as needed.
  1412. //
  1413. if (adapterInfo != NULL) {
  1414. BOOLEAN somethingChanged = FALSE;
  1415. BOOL netNameHasPrecedence = NetNameHasPrecedence;
  1416. LPWSTR address = NULL;
  1417. LPWSTR adapterName = NULL;
  1418. LPWSTR adapterId = NULL;
  1419. LPWSTR networkName = NULL;
  1420. if (newAdapter) {
  1421. netNameHasPrecedence = TRUE;
  1422. adapterId = adapterInfo->DeviceGuid;
  1423. somethingChanged = TRUE;
  1424. }
  1425. //
  1426. // If the address value has changed, update it
  1427. //
  1428. if (lstrcmpW(
  1429. interfaceInfo->Address,
  1430. adapterIfInfo->InterfaceAddressString
  1431. ) != 0
  1432. )
  1433. {
  1434. ClNetDbgPrint((
  1435. LOG_NOISE,
  1436. "[ClNet] The address for the network interface has "
  1437. "changed to %1!ws!.\n",
  1438. adapterIfInfo->InterfaceAddressString
  1439. ));
  1440. address = adapterIfInfo->InterfaceAddressString;
  1441. somethingChanged = TRUE;
  1442. }
  1443. //
  1444. // If the adapter name changed, update it.
  1445. //
  1446. if (lstrcmpW(
  1447. interfaceInfo->AdapterName,
  1448. adapterInfo->DeviceName
  1449. ) != 0
  1450. )
  1451. {
  1452. if (!newAdapter) {
  1453. ClNetDbgPrint((
  1454. LOG_NOISE,
  1455. "[ClNet] The adapter name for the network "
  1456. "interface has changed to '%1!ws!'.\n",
  1457. adapterInfo->DeviceName
  1458. ));
  1459. }
  1460. adapterName = adapterInfo->DeviceName;
  1461. somethingChanged = TRUE;
  1462. }
  1463. //
  1464. // If the connectoid name is different, choose the correct
  1465. // name based on the name precedence and update the
  1466. // network, connectoid, and interface names as
  1467. // appropriate.
  1468. //
  1469. if (lstrcmpW(
  1470. networkInfo->Name,
  1471. adapterInfo->ConnectoidName
  1472. ) != 0
  1473. )
  1474. {
  1475. if (netNameHasPrecedence) {
  1476. //
  1477. // Update the local connectoid name.
  1478. //
  1479. DWORD status;
  1480. ClNetDbgPrint((LOG_NOISE,
  1481. "[ClNet] Changing name of connectoid '%1!ws!' "
  1482. "(%2!ws!) to match name of cluster "
  1483. "network '%3!ws'\n",
  1484. adapterInfo->ConnectoidName,
  1485. adapterInfo->DeviceGuid,
  1486. networkInfo->Name
  1487. ));
  1488. status = ClRtlFindConnectoidByGuidAndSetName(
  1489. adapterInfo->DeviceGuid,
  1490. networkInfo->Name
  1491. );
  1492. if ( status != ERROR_SUCCESS ) {
  1493. ClNetDbgPrint((LOG_UNUSUAL,
  1494. "[ClNet] Failed to change name of "
  1495. "connectoid from '%1!ws!' to '%2!ws!', "
  1496. "status %3!u!\n",
  1497. adapterInfo->ConnectoidName,
  1498. networkInfo->Name,
  1499. status
  1500. ));
  1501. }
  1502. }
  1503. else {
  1504. //
  1505. // Update the network name. The connectoid name
  1506. // may get tweaked for uniqueness as a side
  1507. // effect.
  1508. //
  1509. ClNetDbgPrint((LOG_UNUSUAL,
  1510. "[ClNet] Changing name of cluster "
  1511. "network '%1!ws!' (%2!ws!) to match name of "
  1512. "connectoid '%3!ws!'.\n",
  1513. networkInfo->Name,
  1514. networkInfo->Id,
  1515. adapterInfo->ConnectoidName
  1516. ));
  1517. networkName = ClNetpMakeUniqueNetworkName(
  1518. adapterInfo->ConnectoidName,
  1519. adapterInfo->DeviceGuid,
  1520. ConfigLists,
  1521. &unchangedConfigList
  1522. );
  1523. if (networkName == NULL) {
  1524. status = ERROR_NOT_ENOUGH_MEMORY;
  1525. goto error_exit;
  1526. }
  1527. ClNetDbgPrint((
  1528. LOG_NOISE,
  1529. "[ClNet] Changed name of cluster "
  1530. "network '%1!ws!' (%2!ws!) to '%3!ws!'.\n",
  1531. networkInfo->Name,
  1532. networkInfo->Id,
  1533. networkName
  1534. ));
  1535. LocalFree(networkInfo->Name);
  1536. networkInfo->Name = networkName;
  1537. configEntry->UpdateNetworkName = TRUE;
  1538. somethingChanged = TRUE;
  1539. }
  1540. }
  1541. if (somethingChanged) {
  1542. ClNetDbgPrint((
  1543. LOG_NOISE,
  1544. "[ClNet] Updating configuration info for "
  1545. "interface '%1!ws!' (%2!ws!).\n",
  1546. interfaceInfo->Name,
  1547. interfaceInfo->Id
  1548. ));
  1549. status = ClNetpUpdateConfigEntry(
  1550. configEntry,
  1551. address,
  1552. adapterId,
  1553. adapterName,
  1554. LocalNodeName,
  1555. networkName
  1556. );
  1557. if (status != ERROR_SUCCESS) {
  1558. goto error_exit;
  1559. }
  1560. //
  1561. // Move the entry to the updated interface list
  1562. //
  1563. RemoveEntryList(&(configEntry->Linkage));
  1564. InsertTailList(
  1565. &(ConfigLists->UpdatedInterfaceList),
  1566. &(configEntry->Linkage)
  1567. );
  1568. }
  1569. else {
  1570. //
  1571. // Move the entry to the unchanged list
  1572. //
  1573. RemoveEntryList(&(configEntry->Linkage));
  1574. InsertTailList(
  1575. &unchangedConfigList,
  1576. &(configEntry->Linkage)
  1577. );
  1578. }
  1579. }
  1580. else {
  1581. //
  1582. // This node is no longer attached to this network.
  1583. //
  1584. ClNetDbgPrint((
  1585. LOG_NOISE,
  1586. "[ClNet] This node is no longer attached to "
  1587. "network '%1!ws!' (%2!ws!).\n",
  1588. networkInfo->Name,
  1589. networkInfo->Id
  1590. ));
  1591. (*pClNetLogEvent3)(
  1592. LOG_NOISE,
  1593. CLNET_EVENT_DELETE_INTERFACE,
  1594. networkInfo->Name,
  1595. interfaceInfo->AdapterName,
  1596. interfaceInfo->Name
  1597. );
  1598. ClNetDbgPrint((
  1599. LOG_NOISE,
  1600. "[ClNet] Deleting interface '%1!ws!' (%2!ws!) from the "
  1601. "cluster configuration.\n",
  1602. interfaceInfo->Name,
  1603. interfaceInfo->Id
  1604. ));
  1605. //
  1606. // Move the entry to the deleted interface list.
  1607. //
  1608. RemoveEntryList(&(configEntry->Linkage));
  1609. InsertTailList(
  1610. &(ConfigLists->DeletedInterfaceList),
  1611. &(configEntry->Linkage)
  1612. );
  1613. }
  1614. }
  1615. else {
  1616. //
  1617. // This node was not previously attached to this network.
  1618. // Search for a new attachment.
  1619. //
  1620. ClNetDbgPrint((
  1621. LOG_NOISE,
  1622. "[ClNet] This node was not previously attached to "
  1623. "network '%1!ws!' (%2!ws!).\n",
  1624. networkInfo->Name,
  1625. networkInfo->Id
  1626. ));
  1627. ClNetDbgPrint((
  1628. LOG_NOISE,
  1629. "[ClNet] Searching for a new attachment...\n"
  1630. ));
  1631. adapterInfo = ClRtlFindNetAdapterByNetworkAddress(
  1632. adapterEnum,
  1633. networkInfo->Address,
  1634. &adapterIfInfo
  1635. );
  1636. if (adapterInfo != NULL) {
  1637. //
  1638. // Found a new adapter which is attached to this network.
  1639. // Create a new interface definition for it.
  1640. //
  1641. ClNetDbgPrint((
  1642. LOG_NOISE,
  1643. "[ClNet] Adapter '%1!ws!' (%2!ws!) is attached to "
  1644. "network %3!ws!.\n",
  1645. adapterInfo->DeviceName,
  1646. adapterInfo->DeviceGuid,
  1647. networkInfo->Name
  1648. ));
  1649. //
  1650. // Network name has precedence.
  1651. // Update the local connectoid name if necessary.
  1652. //
  1653. if (lstrcmpW(
  1654. networkInfo->Name,
  1655. adapterInfo->ConnectoidName
  1656. ) != 0
  1657. )
  1658. {
  1659. DWORD status;
  1660. ClNetDbgPrint((LOG_NOISE,
  1661. "[ClNet] Changing name of connectoid '%1!ws!' (%2!ws!) "
  1662. "to match name of cluster network '%3!ws!'\n",
  1663. adapterInfo->ConnectoidName,
  1664. adapterInfo->DeviceGuid,
  1665. networkInfo->Name
  1666. ));
  1667. status = ClRtlFindConnectoidByGuidAndSetName(
  1668. adapterInfo->DeviceGuid,
  1669. networkInfo->Name
  1670. );
  1671. if ( status != ERROR_SUCCESS ) {
  1672. ClNetDbgPrint((
  1673. LOG_UNUSUAL,
  1674. "[ClNet] Failed to change name of connectoid "
  1675. "'%1!ws!' (%2!ws!) to '%3!ws!', status %4!u!.\n",
  1676. adapterInfo->ConnectoidName,
  1677. adapterInfo->DeviceGuid,
  1678. networkInfo->Name,
  1679. status
  1680. ));
  1681. }
  1682. }
  1683. status = ClNetpCreateConfigEntryInterface(
  1684. configEntry,
  1685. LocalNodeName,
  1686. LocalNodeId,
  1687. adapterInfo,
  1688. adapterIfInfo,
  1689. DefaultClusnetEndpoint
  1690. );
  1691. if (status != ERROR_SUCCESS) {
  1692. goto error_exit;
  1693. }
  1694. ClNetDbgPrint((
  1695. LOG_NOISE,
  1696. "[ClNet] Created cluster interface '%1!ws!' (%2!ws!).\n",
  1697. configEntry->InterfaceInfo.Name,
  1698. configEntry->InterfaceInfo.Id
  1699. ));
  1700. //
  1701. // Put the entry on the created interface list
  1702. //
  1703. RemoveEntryList(&(configEntry->Linkage));
  1704. InsertTailList(
  1705. &(ConfigLists->CreatedInterfaceList),
  1706. &(configEntry->Linkage)
  1707. );
  1708. }
  1709. else {
  1710. ClNetDbgPrint((
  1711. LOG_NOISE,
  1712. "[ClNet] This node is not attached to network '%1!ws!'.\n",
  1713. networkInfo->Name
  1714. ));
  1715. //
  1716. // Move the entry to the unchanged list
  1717. //
  1718. RemoveEntryList(&(configEntry->Linkage));
  1719. InsertTailList(&unchangedConfigList, &(configEntry->Linkage));
  1720. }
  1721. }
  1722. //
  1723. // If we found an adapter on this network, then mark it as
  1724. // consumed.
  1725. //
  1726. if (adapterInfo != NULL) {
  1727. //
  1728. // Consume the adapter
  1729. adapterInfo->Ignore = TRUE;
  1730. //
  1731. //
  1732. // Consume all other adapters that are attached to this
  1733. // network
  1734. //
  1735. ClNetpConsumeAdaptersOnNetwork(
  1736. adapterEnum,
  1737. adapterIfInfo->NetworkAddressString
  1738. );
  1739. matchedNetworkCount++;
  1740. }
  1741. }
  1742. //
  1743. // Phase 2
  1744. //
  1745. // Create new networks for any remaining adapters.
  1746. //
  1747. ClNetDbgPrint((
  1748. LOG_NOISE,
  1749. "[ClNet] Phase 2 - Creating new networks for all remaining "
  1750. "adapters.\n"
  1751. ));
  1752. for (adapterInfo = adapterEnum->AdapterList;
  1753. adapterInfo != NULL;
  1754. adapterInfo = adapterInfo->Next
  1755. )
  1756. {
  1757. if ( !adapterInfo->Ignore && (adapterInfo->InterfaceCount > 0) ) {
  1758. LPWSTR newNetworkName;
  1759. (*pClNetLogEvent1)(
  1760. LOG_NOISE,
  1761. CLNET_EVENT_CREATE_NETWORK,
  1762. adapterInfo->ConnectoidName
  1763. );
  1764. ClNetDbgPrint((
  1765. LOG_NOISE,
  1766. "[ClNet] Creating new network & interface for "
  1767. "adapter '%1!ws!'.\n",
  1768. adapterInfo->DeviceName
  1769. ));
  1770. //
  1771. // Create a unique network name based on the connectoid name.
  1772. // The connectoid name may get tweaked for uniqueness as a
  1773. // side effect.
  1774. //
  1775. newNetworkName = ClNetpMakeUniqueNetworkName(
  1776. adapterInfo->ConnectoidName,
  1777. adapterInfo->DeviceGuid,
  1778. ConfigLists,
  1779. &unchangedConfigList
  1780. );
  1781. if (newNetworkName == NULL) {
  1782. status = ERROR_NOT_ENOUGH_MEMORY;
  1783. goto error_exit;
  1784. }
  1785. adapterIfInfo = ClRtlGetPrimaryNetInterface(adapterInfo);
  1786. if (adapterIfInfo == NULL) {
  1787. ClNetDbgPrint((
  1788. LOG_NOISE,
  1789. "[ClNet] Not creating network for adapter "
  1790. " '%1!ws!' (%2!ws!) because its primary net "
  1791. "interface could not be found.\n",
  1792. adapterInfo->DeviceName,
  1793. adapterInfo->DeviceGuid
  1794. ));
  1795. LocalFree(newNetworkName);
  1796. goto error_exit;
  1797. }
  1798. configEntry = ClNetpCreateConfigEntry(
  1799. LocalNodeName,
  1800. LocalNodeId,
  1801. newNetworkName,
  1802. DefaultNetworkRole,
  1803. CLNET_DEFAULT_NETWORK_PRIORITY,
  1804. adapterInfo,
  1805. adapterIfInfo,
  1806. DefaultClusnetEndpoint
  1807. );
  1808. LocalFree(newNetworkName);
  1809. if (configEntry == NULL) {
  1810. ClNetDbgPrint((
  1811. LOG_NOISE,
  1812. "[ClNet] Failed to create new network & interface "
  1813. "for adapter '%1!ws!' (%2!ws!)\n",
  1814. adapterInfo->DeviceName,
  1815. adapterInfo->DeviceGuid
  1816. ));
  1817. goto error_exit;
  1818. }
  1819. ClNetDbgPrint((
  1820. LOG_NOISE,
  1821. "[ClNet] Created interface '%1!ws!' (%2!ws!).\n",
  1822. configEntry->InterfaceInfo.Name,
  1823. configEntry->InterfaceInfo.Id
  1824. ));
  1825. ClNetDbgPrint((
  1826. LOG_NOISE,
  1827. "[ClNet] Created network '%1!ws!' (%2!ws!).\n",
  1828. configEntry->NetworkInfo.Name,
  1829. configEntry->NetworkInfo.Id
  1830. ));
  1831. InsertTailList(
  1832. &(ConfigLists->CreatedNetworkList),
  1833. &(configEntry->Linkage)
  1834. );
  1835. //
  1836. // Consume the adapter
  1837. adapterInfo->Ignore = TRUE;
  1838. //
  1839. //
  1840. // Consume all other adapters that are attached to this
  1841. // network
  1842. //
  1843. ClNetpConsumeAdaptersOnNetwork(
  1844. adapterEnum,
  1845. adapterIfInfo->NetworkAddressString
  1846. );
  1847. newNetworkCount++;
  1848. }
  1849. }
  1850. status = ERROR_SUCCESS;
  1851. *MatchedNetworkCount = matchedNetworkCount;
  1852. *NewNetworkCount = newNetworkCount;
  1853. error_exit:
  1854. //
  1855. // Move unchanged entries back to the input list.
  1856. //
  1857. while (!IsListEmpty(&unchangedConfigList)) {
  1858. listEntry = RemoveHeadList(&(unchangedConfigList));
  1859. InsertTailList(&(ConfigLists->InputConfigList), listEntry);
  1860. }
  1861. //
  1862. // Free the adapter resources
  1863. //
  1864. if (adapterEnum != NULL) {
  1865. ClRtlFreeNetAdapterEnum(adapterEnum);
  1866. }
  1867. if (eventCode != 0) {
  1868. wsprintfW(&(errorString[0]), L"%u", status);
  1869. (*pClNetLogEvent1)(LOG_CRITICAL, eventCode, errorString);
  1870. }
  1871. if (status == ERROR_SUCCESS) {
  1872. ClNetDbgPrint((LOG_NOISE,
  1873. "[ClNet] Network configuration complete...\n"
  1874. ));
  1875. }
  1876. return(status);
  1877. } // ClNetConfigureNetworks
  1878. 
  1879.