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.

1052 lines
25 KiB

  1. #include <nt.h>
  2. #include <ntrtl.h>
  3. #include <nturtl.h>
  4. #include <windows.h>
  5. #include <objbase.h>
  6. #include <wchar.h>
  7. #include <cluster.h>
  8. #include <clusrpc.h>
  9. #include <clnetcfg.h>
  10. #include <iphlpapi.h>
  11. #include <winsock2.h>
  12. #define NM_WCSLEN(_string) ((lstrlenW(_string) + 1) * sizeof(WCHAR))
  13. CLNET_CONFIG_LISTS ConfigLists;
  14. LPWSTR NodeName = L"TestComputer";
  15. LPWSTR NodeId = L"1";
  16. #if 0
  17. #include <dm.h>
  18. #include <dmp.h>
  19. HKEY DmpRoot;
  20. LIST_ENTRY KeyList;
  21. CRITICAL_SECTION KeyLock;
  22. HDMKEY DmClusterParametersKey;
  23. HDMKEY DmResourcesKey;
  24. HDMKEY DmResourceTypesKey;
  25. HDMKEY DmGroupsKey;
  26. HDMKEY DmNodesKey;
  27. HDMKEY DmNetworksKey;
  28. HDMKEY DmNetInterfacesKey;
  29. HDMKEY DmQuorumKey;
  30. HANDLE ghQuoLogOpenEvent=NULL;
  31. typedef struct _DMP_KEY_DEF {
  32. HDMKEY *pKey;
  33. LPWSTR Name;
  34. } DMP_KEY_DEF;
  35. DMP_KEY_DEF DmpKeyTable[] = {
  36. {&DmResourcesKey, CLUSREG_KEYNAME_RESOURCES},
  37. {&DmResourceTypesKey, CLUSREG_KEYNAME_RESOURCE_TYPES},
  38. {&DmQuorumKey, CLUSREG_KEYNAME_QUORUM},
  39. {&DmGroupsKey, CLUSREG_KEYNAME_GROUPS},
  40. {&DmNodesKey, CLUSREG_KEYNAME_NODES},
  41. {&DmNetworksKey, CLUSREG_KEYNAME_NETWORKS},
  42. {&DmNetInterfacesKey, CLUSREG_KEYNAME_NETINTERFACES}};
  43. #endif
  44. VOID
  45. ClNetPrint(
  46. IN ULONG LogLevel,
  47. IN PCHAR FormatString,
  48. ...
  49. )
  50. {
  51. CHAR buffer[256];
  52. DWORD bytes;
  53. va_list argList;
  54. va_start(argList, FormatString);
  55. bytes = FormatMessageA(
  56. FORMAT_MESSAGE_FROM_STRING,
  57. FormatString,
  58. 0,
  59. 0,
  60. buffer,
  61. sizeof(buffer),
  62. &argList
  63. );
  64. va_end(argList);
  65. if (bytes != 0) {
  66. printf("%s", buffer);
  67. }
  68. return;
  69. } // ClNetPrint
  70. VOID
  71. ClNetLogEvent(
  72. IN DWORD LogLevel,
  73. IN DWORD MessageId
  74. )
  75. {
  76. return;
  77. } // ClNetLogEvent
  78. VOID
  79. ClNetLogEvent1(
  80. IN DWORD LogLevel,
  81. IN DWORD MessageId,
  82. IN LPCWSTR Arg1
  83. )
  84. {
  85. return;
  86. } // ClNetLogEvent1
  87. VOID
  88. ClNetLogEvent2(
  89. IN DWORD LogLevel,
  90. IN DWORD MessageId,
  91. IN LPCWSTR Arg1,
  92. IN LPCWSTR Arg2
  93. )
  94. {
  95. return;
  96. } // ClNetLogEvent2
  97. VOID
  98. ClNetLogEvent3(
  99. IN DWORD LogLevel,
  100. IN DWORD MessageId,
  101. IN LPCWSTR Arg1,
  102. IN LPCWSTR Arg2,
  103. IN LPCWSTR Arg3
  104. )
  105. {
  106. return;
  107. } // ClNetLogEvent3
  108. void
  109. PrintConfigEntry(
  110. PCLNET_CONFIG_ENTRY ConfigEntry
  111. )
  112. {
  113. PNM_NETWORK_INFO Network = &(ConfigEntry->NetworkInfo);
  114. PNM_INTERFACE_INFO Interface = &(ConfigEntry->InterfaceInfo);
  115. printf("\t*************\n");
  116. printf("\tNet Id\t\t%ws\n", Network->Id);
  117. printf("\tName\t\t%ws\n", Network->Name);
  118. printf("\tDesc\t\t%ws\n", Network->Description);
  119. printf("\tRole\t\t%u\n", Network->Role);
  120. printf("\tPriority\t%u\n", Network->Priority);
  121. printf("\tTransport\t%ws\n", Network->Transport);
  122. printf("\tAddress\t\t%ws\n", Network->Address);
  123. printf("\tMask\t\t%ws\n", Network->AddressMask);
  124. printf("\tIf Id\t\t%ws\n", Interface->Id);
  125. printf("\tName\t\t%ws\n", Interface->Name);
  126. printf("\tDesc\t\t%ws\n", Interface->Description);
  127. printf("\tNodeId\t\t%ws\n", Interface->NodeId);
  128. printf("\tAdapter\t\t%ws\n", Interface->Adapter);
  129. printf("\tAddress\t\t%ws\n", Interface->Address);
  130. printf("\tEndpoint\t%ws\n", Interface->ClusnetEndpoint);
  131. printf("\tState\t\t%u\n\n", Interface->State);
  132. return;
  133. }
  134. void
  135. PrintResults(void)
  136. {
  137. PCLNET_CONFIG_ENTRY configEntry;
  138. PLIST_ENTRY listEntry;
  139. printf("Renamed interface list:\n");
  140. for ( listEntry = ConfigLists.RenamedInterfaceList.Flink;
  141. listEntry != &ConfigLists.RenamedInterfaceList;
  142. listEntry = listEntry->Flink
  143. )
  144. {
  145. configEntry = CONTAINING_RECORD(
  146. listEntry,
  147. CLNET_CONFIG_ENTRY,
  148. Linkage
  149. );
  150. PrintConfigEntry(configEntry);
  151. }
  152. printf("Deleted interface list:\n");
  153. for ( listEntry = ConfigLists.DeletedInterfaceList.Flink;
  154. listEntry != &ConfigLists.DeletedInterfaceList;
  155. listEntry = listEntry->Flink
  156. )
  157. {
  158. configEntry = CONTAINING_RECORD(
  159. listEntry,
  160. CLNET_CONFIG_ENTRY,
  161. Linkage
  162. );
  163. PrintConfigEntry(configEntry);
  164. }
  165. printf("Updated interface list:\n");
  166. for ( listEntry = ConfigLists.UpdatedInterfaceList.Flink;
  167. listEntry != &ConfigLists.UpdatedInterfaceList;
  168. listEntry = listEntry->Flink
  169. )
  170. {
  171. configEntry = CONTAINING_RECORD(
  172. listEntry,
  173. CLNET_CONFIG_ENTRY,
  174. Linkage
  175. );
  176. PrintConfigEntry(configEntry);
  177. }
  178. printf("Created interface list:\n");
  179. for ( listEntry = ConfigLists.CreatedInterfaceList.Flink;
  180. listEntry != &ConfigLists.CreatedInterfaceList;
  181. listEntry = listEntry->Flink
  182. )
  183. {
  184. configEntry = CONTAINING_RECORD(
  185. listEntry,
  186. CLNET_CONFIG_ENTRY,
  187. Linkage
  188. );
  189. PrintConfigEntry(configEntry);
  190. }
  191. printf("Created network list:\n");
  192. for ( listEntry = ConfigLists.CreatedNetworkList.Flink;
  193. listEntry != &ConfigLists.CreatedNetworkList;
  194. listEntry = listEntry->Flink
  195. )
  196. {
  197. configEntry = CONTAINING_RECORD(
  198. listEntry,
  199. CLNET_CONFIG_ENTRY,
  200. Linkage
  201. );
  202. PrintConfigEntry(configEntry);
  203. }
  204. printf("Unchanged interface list:\n");
  205. for ( listEntry = ConfigLists.InputConfigList.Flink;
  206. listEntry != &ConfigLists.InputConfigList;
  207. listEntry = listEntry->Flink
  208. )
  209. {
  210. configEntry = CONTAINING_RECORD(
  211. listEntry,
  212. CLNET_CONFIG_ENTRY,
  213. Linkage
  214. );
  215. PrintConfigEntry(configEntry);
  216. }
  217. return;
  218. }
  219. void
  220. ConsolidateLists(
  221. PLIST_ENTRY MasterList,
  222. PLIST_ENTRY OtherList
  223. )
  224. {
  225. PLIST_ENTRY entry;
  226. while (!IsListEmpty(OtherList)) {
  227. entry = RemoveHeadList(OtherList);
  228. InsertTailList(MasterList, entry);
  229. }
  230. return;
  231. }
  232. #if 0
  233. DWORD
  234. DmpOpenKeys(
  235. IN REGSAM samDesired
  236. )
  237. /*++
  238. Routine Description:
  239. Opens all the standard cluster registry keys. If any of the
  240. keys are already opened, they will be closed and reopened.
  241. Arguments:
  242. samDesired - Supplies the access that the keys will be opened with.
  243. Return Value:
  244. ERROR_SUCCESS if successful.
  245. Win32 error code otherwise.
  246. --*/
  247. {
  248. DWORD i;
  249. DWORD status;
  250. status = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
  251. L"Cluster",
  252. 0,
  253. samDesired,
  254. &ClusterRegKey);
  255. if ( status == ERROR_SUCCESS ) {
  256. for (i=0;
  257. i<sizeof(DmpKeyTable)/sizeof(DMP_KEY_DEF);
  258. i++) {
  259. *DmpKeyTable[i].pKey = DmOpenKey(DmClusterParametersKey,
  260. DmpKeyTable[i].Name,
  261. samDesired);
  262. if (*DmpKeyTable[i].pKey == NULL) {
  263. Status = GetLastError();
  264. CsDbgPrint(LOG_CRITICAL,
  265. ("[DM]: Failed to open key %1!ws!, status %2!u!\n",
  266. DmpKeyTable[i].Name,
  267. Status));
  268. CL_UNEXPECTED_ERROR( Status );
  269. return(Status);
  270. }
  271. }
  272. }
  273. return status;
  274. }
  275. HDMKEY
  276. DmOpenKey(
  277. IN HDMKEY hKey,
  278. IN LPCWSTR lpSubKey,
  279. IN DWORD samDesired
  280. )
  281. /*++
  282. Routine Description:
  283. Opens a key in the cluster registry. If the key exists, it
  284. is opened. If it does not exist, the call fails.
  285. Arguments:
  286. hKey - Supplies the key that the open is relative to.
  287. lpSubKey - Supplies the key name relative to hKey
  288. samDesired - Supplies desired security access mask
  289. Return Value:
  290. A handle to the specified key if successful
  291. NULL otherwise. LastError will be set to the specific error code.
  292. --*/
  293. {
  294. PDMKEY Parent;
  295. PDMKEY Key=NULL;
  296. DWORD NameLength;
  297. DWORD Status = ERROR_SUCCESS;
  298. Parent = (PDMKEY)hKey;
  299. //check if the key was deleted and invalidated
  300. if (ISKEYDELETED(Parent))
  301. {
  302. Status = ERROR_KEY_DELETED;
  303. goto FnExit;
  304. }
  305. //
  306. // Allocate the DMKEY structure.
  307. //
  308. NameLength = (lstrlenW(Parent->Name) + 1 + lstrlenW(lpSubKey) + 1)*sizeof(WCHAR);
  309. Key = LocalAlloc(LMEM_FIXED, sizeof(DMKEY)+NameLength);
  310. if (Key == NULL) {
  311. Status = ERROR_NOT_ENOUGH_MEMORY;
  312. CL_UNEXPECTED_ERROR(Status);
  313. goto FnExit;
  314. }
  315. //
  316. // Open the key on the local machine.
  317. //
  318. Status = RegOpenKeyEx(Parent->hKey,
  319. lpSubKey,
  320. 0,
  321. samDesired,
  322. &Key->hKey);
  323. if (Status != ERROR_SUCCESS) {
  324. goto FnExit;
  325. }
  326. //
  327. // Create the key name
  328. //
  329. lstrcpyW(Key->Name, Parent->Name);
  330. if (Key->Name[0] != UNICODE_NULL) {
  331. lstrcatW(Key->Name, L"\\");
  332. }
  333. lstrcatW(Key->Name, lpSubKey);
  334. Key->GrantedAccess = samDesired;
  335. EnterCriticalSection(&KeyLock);
  336. InsertHeadList(&KeyList, &Key->ListEntry);
  337. InitializeListHead(&Key->NotifyList);
  338. LeaveCriticalSection(&KeyLock);
  339. FnExit:
  340. if (Status != ERROR_SUCCESS)
  341. {
  342. if (Key) LocalFree(Key);
  343. SetLastError(Status);
  344. return(NULL);
  345. }
  346. else
  347. return((HDMKEY)Key);
  348. }
  349. DWORD
  350. NmpQueryString(
  351. IN HDMKEY Key,
  352. IN LPCWSTR ValueName,
  353. IN DWORD ValueType,
  354. IN LPWSTR *StringBuffer,
  355. IN OUT LPDWORD StringBufferSize,
  356. OUT LPDWORD StringSize
  357. )
  358. /*++
  359. Routine Description:
  360. Reads a REG_SZ or REG_MULTI_SZ registry value. If the StringBuffer is
  361. not large enough to hold the data, it is reallocated.
  362. Arguments:
  363. Key - Open key for the value to be read.
  364. ValueName - Unicode name of the value to be read.
  365. ValueType - REG_SZ or REG_MULTI_SZ.
  366. StringBuffer - Buffer into which to place the value data.
  367. StringBufferSize - Pointer to the size of the StringBuffer. This parameter
  368. is updated if StringBuffer is reallocated.
  369. StringSize - The size of the data returned in StringBuffer, including
  370. the terminating null character.
  371. Return Value:
  372. The status of the registry query.
  373. --*/
  374. {
  375. DWORD status;
  376. DWORD valueType;
  377. WCHAR *temp;
  378. DWORD oldBufferSize = *StringBufferSize;
  379. BOOL noBuffer = FALSE;
  380. if (*StringBufferSize == 0) {
  381. noBuffer = TRUE;
  382. }
  383. *StringSize = *StringBufferSize;
  384. status = DmQueryValue( Key,
  385. ValueName,
  386. &valueType,
  387. (LPBYTE) *StringBuffer,
  388. StringSize
  389. );
  390. if (status == NO_ERROR) {
  391. if (!noBuffer ) {
  392. if (valueType == ValueType) {
  393. return(NO_ERROR);
  394. }
  395. else {
  396. return(ERROR_INVALID_PARAMETER);
  397. }
  398. }
  399. status = ERROR_MORE_DATA;
  400. }
  401. if (status == ERROR_MORE_DATA) {
  402. temp = MIDL_user_allocate(*StringSize);
  403. if (temp == NULL) {
  404. *StringSize = 0;
  405. return(ERROR_NOT_ENOUGH_MEMORY);
  406. }
  407. if (!noBuffer) {
  408. MIDL_user_free(*StringBuffer);
  409. }
  410. *StringBuffer = temp;
  411. *StringBufferSize = *StringSize;
  412. status = DmQueryValue( Key,
  413. ValueName,
  414. &valueType,
  415. (LPBYTE) *StringBuffer,
  416. StringSize
  417. );
  418. if (status == NO_ERROR) {
  419. if (valueType == ValueType) {
  420. return(NO_ERROR);
  421. }
  422. else {
  423. *StringSize = 0;
  424. return(ERROR_INVALID_PARAMETER);
  425. }
  426. }
  427. }
  428. return(status);
  429. } // NmpQueryString
  430. DWORD
  431. NmpGetNetworkDefinition(
  432. IN LPWSTR NetworkId,
  433. OUT PNM_NETWORK_INFO NetworkInfo
  434. )
  435. /*++
  436. Routine Description:
  437. Reads information about a defined cluster network from the cluster
  438. database and fills in a structure describing it.
  439. Arguments:
  440. NetworkId - A pointer to a unicode string containing the ID of the
  441. network to query.
  442. NetworkInfo - A pointer to the network info structure to fill in.
  443. Return Value:
  444. ERROR_SUCCESS if the routine succeeds.
  445. A Win32 error code otherwise.
  446. --*/
  447. {
  448. DWORD status;
  449. HDMKEY networkKey = NULL;
  450. DWORD valueLength, valueSize;
  451. DWORD i;
  452. PNM_INTERFACE_ENUM interfaceEnum;
  453. ZeroMemory(NetworkInfo, sizeof(NM_NETWORK_INFO));
  454. //
  455. // Open the network's key.
  456. //
  457. networkKey = DmOpenKey(DmNetworksKey, NetworkId, KEY_READ);
  458. if (networkKey == NULL) {
  459. status = GetLastError();
  460. ClNetPrint(LOG_CRITICAL,
  461. "[NM] Failed to open network key, status %1!u!\n",
  462. status
  463. );
  464. goto error_exit;
  465. }
  466. //
  467. // Copy the ID value.
  468. //
  469. NetworkInfo->Id = MIDL_user_allocate(NM_WCSLEN(NetworkId));
  470. if (NetworkInfo->Id == NULL) {
  471. status = ERROR_NOT_ENOUGH_MEMORY;
  472. goto error_exit;
  473. }
  474. wcscpy(NetworkInfo->Id, NetworkId);
  475. //
  476. // Read the network's name.
  477. //
  478. valueLength = 0;
  479. status = NmpQueryString(
  480. networkKey,
  481. CLUSREG_NAME_NET_NAME,
  482. REG_SZ,
  483. &(NetworkInfo->Name),
  484. &valueLength,
  485. &valueSize
  486. );
  487. if (status != ERROR_SUCCESS) {
  488. ClNetPrint(LOG_CRITICAL,
  489. "[NM] Query of name value failed for network %1!ws!, status %2!u!.\n",
  490. NetworkId,
  491. status
  492. );
  493. goto error_exit;
  494. }
  495. //
  496. // Read the description value.
  497. //
  498. valueLength = 0;
  499. status = NmpQueryString(
  500. networkKey,
  501. CLUSREG_NAME_NET_DESC,
  502. REG_SZ,
  503. &(NetworkInfo->Description),
  504. &valueLength,
  505. &valueSize
  506. );
  507. if (status != ERROR_SUCCESS) {
  508. ClNetPrint(LOG_CRITICAL,
  509. "[NM] Query of description value failed for network %1!ws!, status %2!u!.\n",
  510. NetworkId,
  511. status
  512. );
  513. goto error_exit;
  514. }
  515. //
  516. // Read the role value.
  517. //
  518. status = DmQueryDword(
  519. networkKey,
  520. CLUSREG_NAME_NET_ROLE,
  521. &(NetworkInfo->Role),
  522. NULL
  523. );
  524. if (status != ERROR_SUCCESS) {
  525. ClNetPrint(LOG_CRITICAL,
  526. "[NM] Query of role value failed for network %1!ws!, status %2!u!.\n",
  527. NetworkId,
  528. status
  529. );
  530. goto error_exit;
  531. }
  532. //
  533. // Read the priority value.
  534. //
  535. status = DmQueryDword(
  536. networkKey,
  537. CLUSREG_NAME_NET_PRIORITY,
  538. &(NetworkInfo->Priority),
  539. NULL
  540. );
  541. if (status != ERROR_SUCCESS) {
  542. ClNetPrint(LOG_CRITICAL,
  543. "[NM] Query of priority value failed for network %1!ws!, status %2!u!.\n",
  544. NetworkId,
  545. status
  546. );
  547. goto error_exit;
  548. }
  549. //
  550. // Read the address value.
  551. //
  552. valueLength = 0;
  553. status = NmpQueryString(
  554. networkKey,
  555. CLUSREG_NAME_NET_ADDRESS,
  556. REG_SZ,
  557. &(NetworkInfo->Address),
  558. &valueLength,
  559. &valueSize
  560. );
  561. if (status != ERROR_SUCCESS) {
  562. ClNetPrint(LOG_CRITICAL,
  563. "[NM] Query of address value failed for network %1!ws!, status %2!u!.\n",
  564. NetworkId,
  565. status
  566. );
  567. goto error_exit;
  568. }
  569. //
  570. // Read the address mask.
  571. //
  572. valueLength = 0;
  573. status = NmpQueryString(
  574. networkKey,
  575. CLUSREG_NAME_NET_ADDRESS_MASK,
  576. REG_SZ,
  577. &(NetworkInfo->AddressMask),
  578. &valueLength,
  579. &valueSize
  580. );
  581. if (status != ERROR_SUCCESS) {
  582. ClNetPrint(LOG_CRITICAL,
  583. "[NM] Query of address mask value failed for network %1!ws!, status %2!u!.\n",
  584. NetworkId,
  585. status
  586. );
  587. goto error_exit;
  588. }
  589. //
  590. // Read the transport name.
  591. //
  592. valueLength = 0;
  593. status = NmpQueryString(
  594. networkKey,
  595. CLUSREG_NAME_NET_TRANSPORT,
  596. REG_SZ,
  597. &(NetworkInfo->Transport),
  598. &valueLength,
  599. &valueSize
  600. );
  601. if (status != ERROR_SUCCESS) {
  602. ClNetPrint(LOG_CRITICAL,
  603. "[NM] Query of transport value failed for network %1!ws!, status %2!u!.\n",
  604. NetworkId,
  605. status
  606. );
  607. goto error_exit;
  608. }
  609. error_exit:
  610. if (status != ERROR_SUCCESS) {
  611. ClNetFreeNetworkInfo(NetworkInfo);
  612. }
  613. if (networkKey != NULL) {
  614. DmCloseKey(networkKey);
  615. }
  616. return(status);
  617. } // NmpGetNetworkDefinition
  618. DWORD
  619. NmpEnumNetworkDefinitions(
  620. OUT PNM_NETWORK_ENUM * NetworkEnum
  621. )
  622. /*++
  623. Routine Description:
  624. Reads information about defined cluster networks from the cluster
  625. database. and builds an enumeration structure to hold the information.
  626. Arguments:
  627. NetworkEnum - A pointer to the variable into which to place a pointer to
  628. the allocated network enumeration.
  629. Return Value:
  630. ERROR_SUCCESS if the routine succeeds.
  631. A Win32 error code otherwise.
  632. --*/
  633. {
  634. DWORD status;
  635. PNM_NETWORK_ENUM networkEnum = NULL;
  636. PNM_NETWORK_INFO networkInfo;
  637. WCHAR networkId[CS_NETWORK_ID_LENGTH + 1];
  638. DWORD i;
  639. DWORD valueLength;
  640. DWORD numNetworks;
  641. DWORD ignored;
  642. FILETIME fileTime;
  643. *NetworkEnum = NULL;
  644. //
  645. // First count the number of networks.
  646. //
  647. status = DmQueryInfoKey(
  648. DmNetworksKey,
  649. &numNetworks,
  650. &ignored, // MaxSubKeyLen
  651. &ignored, // Values
  652. &ignored, // MaxValueNameLen
  653. &ignored, // MaxValueLen
  654. &ignored, // lpcbSecurityDescriptor
  655. &fileTime
  656. );
  657. if (status != ERROR_SUCCESS) {
  658. ClNetPrint(LOG_CRITICAL,
  659. "[NM] Failed to query Networks key information, status %1!u!\n",
  660. status
  661. );
  662. return(status);
  663. }
  664. if (numNetworks == 0) {
  665. valueLength = sizeof(NM_NETWORK_ENUM);
  666. }
  667. else {
  668. valueLength = sizeof(NM_NETWORK_ENUM) +
  669. (sizeof(NM_NETWORK_INFO) * (numNetworks-1));
  670. }
  671. valueLength = sizeof(NM_NETWORK_ENUM) +
  672. (sizeof(NM_NETWORK_INFO) * (numNetworks-1));
  673. networkEnum = MIDL_user_allocate(valueLength);
  674. if (networkEnum == NULL) {
  675. ClNetPrint(LOG_CRITICAL, "[NM] Failed to allocate memory.\n");
  676. return(ERROR_NOT_ENOUGH_MEMORY);
  677. }
  678. ZeroMemory(networkEnum, valueLength);
  679. for (i=0; i < numNetworks; i++) {
  680. networkInfo = &(networkEnum->NetworkList[i]);
  681. valueLength = sizeof(networkId);
  682. status = DmEnumKey(
  683. DmNetworksKey,
  684. i,
  685. &(networkId[0]),
  686. &valueLength,
  687. NULL
  688. );
  689. if (status != ERROR_SUCCESS) {
  690. ClNetPrint(LOG_CRITICAL,
  691. "[NM] Failed to enumerate network key, status %1!u!\n",
  692. status
  693. );
  694. goto error_exit;
  695. }
  696. status = NmpGetNetworkDefinition(networkId, networkInfo);
  697. if (status != ERROR_SUCCESS) {
  698. goto error_exit;
  699. }
  700. networkEnum->NetworkCount++;
  701. }
  702. *NetworkEnum = networkEnum;
  703. return(ERROR_SUCCESS);
  704. error_exit:
  705. if (networkEnum != NULL) {
  706. ClNetFreeNetworkEnum(networkEnum);
  707. }
  708. return(status);
  709. }
  710. DWORD
  711. ReadRegData(
  712. IN PCLNET_CONFIG_LISTS Lists
  713. )
  714. /*++
  715. Read the cluster registry data and bulid up an input list
  716. similar to what happens in the cluster service.
  717. --*/
  718. {
  719. DWORD status;
  720. PNM_NETWORK_ENUM * networkEnum;
  721. PNM_INTERFACE_ENUM * interfaceEnum;
  722. LPWSTR localNodeId;
  723. status = DmpOpenKeys(MAXIMUM_ALLOWED);
  724. if (status != ERROR_SUCCESS) {
  725. CL_UNEXPECTED_ERROR( status );
  726. return(status);
  727. }
  728. status = ClNetConvertEnumsToConfigList(networkEnum,
  729. interfaceEnum,
  730. localNodeId,
  731. &Lists->InputConfigList);
  732. return status;
  733. }
  734. #endif
  735. int _cdecl
  736. main(
  737. int argc,
  738. char** argv
  739. )
  740. {
  741. DWORD status;
  742. DWORD i;
  743. WSADATA wsaData;
  744. WORD versionRequested;
  745. int err;
  746. SOCKET s;
  747. DWORD bytesReturned;
  748. DWORD matchedNetworkCount;
  749. DWORD newNetworkCount;
  750. ClNetInitialize(
  751. ClNetPrint,
  752. ClNetLogEvent,
  753. ClNetLogEvent1,
  754. ClNetLogEvent2,
  755. ClNetLogEvent3
  756. );
  757. ClNetInitializeConfigLists(&ConfigLists);
  758. // ReadRegData( &ConfigLists );
  759. versionRequested = MAKEWORD(2,0);
  760. err = WSAStartup(versionRequested, &wsaData);
  761. if (err != 0) {
  762. status = WSAGetLastError();
  763. printf("wsastartup failed, %u\n", status);
  764. return(1);
  765. }
  766. s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
  767. if (s == INVALID_SOCKET) {
  768. status = WSAGetLastError();
  769. printf("socket failed, %u\n", status);
  770. return(1);
  771. }
  772. //
  773. // Init COM
  774. //
  775. status = CoInitializeEx( NULL, COINIT_DISABLE_OLE1DDE | COINIT_MULTITHREADED );
  776. if ( !SUCCEEDED( status )) {
  777. printf("Couldn't init COM %08X\n", status );
  778. return 1;
  779. }
  780. for (i=0; ; i++) {
  781. printf("\nIteration #%u\n\n", i);
  782. status = ClNetConfigureNetworks(
  783. NodeId,
  784. NodeName,
  785. L"4303",
  786. TRUE,
  787. &ConfigLists,
  788. &matchedNetworkCount,
  789. &newNetworkCount
  790. );
  791. if (status != ERROR_SUCCESS) {
  792. printf("Config failed, status %u\n", status);
  793. return(1);
  794. }
  795. printf("Config succeeded - matched Networks = %u, new Networks = %u\n\n",
  796. matchedNetworkCount, newNetworkCount);
  797. PrintResults();
  798. ClNetFreeConfigList(&ConfigLists.RenamedInterfaceList);
  799. ClNetFreeConfigList(&ConfigLists.DeletedInterfaceList);
  800. ConsolidateLists(
  801. &ConfigLists.InputConfigList,
  802. &ConfigLists.UpdatedInterfaceList
  803. );
  804. ConsolidateLists(
  805. &ConfigLists.InputConfigList,
  806. &ConfigLists.CreatedInterfaceList
  807. );
  808. ConsolidateLists(
  809. &ConfigLists.InputConfigList,
  810. &ConfigLists.CreatedNetworkList
  811. );
  812. printf("Waiting for PnP event\n");
  813. err = WSAIoctl(
  814. s,
  815. SIO_ADDRESS_LIST_CHANGE,
  816. NULL,
  817. 0,
  818. NULL,
  819. 0,
  820. &bytesReturned,
  821. NULL,
  822. NULL
  823. );
  824. if (err != 0) {
  825. status = WSAGetLastError();
  826. printf("wsastartup failed, %u\n", status);
  827. return(1);
  828. }
  829. printf("PnP notification received\n");
  830. }
  831. CoUninitialize();
  832. return(0);
  833. }