/*++ Copyright (c) 1997 Microsoft Corporation Module Name: clnetcfg.c Abstract: System network configuration grovelling routines Author: Mike Massa (mikemas) May 19, 1997 Revision History: Who When What -------- -------- ---------------------------------------------- mikemas 05-19-97 created --*/ #include #include #include #include #include #include #include #include // // Private constants // #define CLNET_DEFAULT_NETWORK_PRIORITY 0xffffffff // // Private Data // LPFN_CLNETPRINT pClNetPrint = NULL; LPFN_CLNETLOGEVENT pClNetLogEvent = NULL; LPFN_CLNETLOGEVENT1 pClNetLogEvent1 = NULL; LPFN_CLNETLOGEVENT2 pClNetLogEvent2 = NULL; LPFN_CLNETLOGEVENT3 pClNetLogEvent3 = NULL; WCHAR ClNetpEmptyString[] = L""; // // Private Macros // #if DBG #define ClNetDbgPrint(arg) (*pClNetPrint) arg #else #define ClNetDbgPrint(arg) #endif // // Private utility routines // VOID ClNetpConsumeAdaptersOnNetwork( IN PCLRTL_NET_ADAPTER_ENUM AdapterEnum, IN LPWSTR NetworkAddress ) { PCLRTL_NET_ADAPTER_INFO adapterInfo; PCLRTL_NET_INTERFACE_INFO adapterIfInfo; ClNetDbgPrint(( LOG_NOISE, "[ClNet] Consuming all adapters on IP network %1!ws!.\n", NetworkAddress )); // // Walk the adapter enum and consume all other adapters // attached to this network. // for (adapterInfo = AdapterEnum->AdapterList; adapterInfo != NULL; adapterInfo = adapterInfo->Next ) { if (adapterInfo->Ignore == FALSE) { adapterIfInfo = ClRtlFindNetInterfaceByNetworkAddress( adapterInfo, NetworkAddress ); if (adapterIfInfo != NULL) { // // This is a duplicate adapter. // ClNetDbgPrint(( LOG_NOISE, "[ClNet] Consumed adapter '%1!ws!'.\n", adapterInfo->DeviceName )); adapterInfo->Ignore = TRUE; } } } ClNetDbgPrint(( LOG_NOISE, "[ClNet] Finished consuming all adapters on IP network %1!ws!.\n", NetworkAddress )); return; } // ClNetpConsumeAdaptersOnNetwork LPWSTR ClNetpCloneString( LPWSTR String ) { LPWSTR newString = LocalAlloc( LMEM_FIXED, (lstrlenW(String) + 1) * sizeof(UNICODE_NULL) ); if (newString != NULL) { lstrcpyW(newString, String); } return(newString); } // ClNetpCloneString BOOLEAN ClNetpIsNetworkNameUnique( IN LPWSTR NetworkName, IN PCLNET_CONFIG_LISTS ConfigLists, IN PLIST_ENTRY UnchangedConfigList ) { PLIST_ENTRY listEntry; PCLNET_CONFIG_ENTRY configEntry; PLIST_ENTRY listHead; ClNetDbgPrint(( LOG_NOISE, "[ClNet] Checking uniqueness of net name '%1!ws!'\n", NetworkName )); // // Check the existing cluster network definitions for a duplicate // listHead = &(ConfigLists->InputConfigList); for (;;) { for (listEntry = listHead->Flink; listEntry != listHead; listEntry = listEntry->Flink ) { configEntry = CONTAINING_RECORD( listEntry, CLNET_CONFIG_ENTRY, Linkage ); if (lstrcmpiW(NetworkName, configEntry->NetworkInfo.Name) == 0) { ClNetDbgPrint(( LOG_NOISE, "[ClNet] Net name '%1!ws!' is not unique\n", NetworkName )); return(FALSE); } } if (listHead == &(ConfigLists->InputConfigList)) { listHead = &(ConfigLists->DeletedInterfaceList); } else if (listHead == &(ConfigLists->DeletedInterfaceList)) { listHead = &(ConfigLists->UpdatedInterfaceList); } else if (listHead == &(ConfigLists->UpdatedInterfaceList)) { listHead = &(ConfigLists->CreatedNetworkList); } else if (listHead == &(ConfigLists->CreatedNetworkList)) { listHead = UnchangedConfigList; } else { break; } } ClNetDbgPrint(( LOG_NOISE, "[ClNet] Net name '%1!ws!' is unique\n", NetworkName )); return(TRUE); } // ClNetpIsNetworkNameUnique LPWSTR ClNetpMakeNetworkName( IN LPWSTR OldNetworkName, IN DWORD InstanceNumber ) { LPWSTR newName, endPtr, truncatePtr, ptr; DWORD length, tempInstance, tempLength; ClNetDbgPrint(( LOG_NOISE, "[ClNet] Attempt to make net name '%1!ws!' unique by appending (%2!u!)\n", OldNetworkName, InstanceNumber )); // // Append (InstanceNumber) to name string // for (endPtr = OldNetworkName, length = 0; *endPtr != UNICODE_NULL; endPtr++, length++ ); // // Check if there is already an instance number appended. // if ( (length > 3) && (*(endPtr - 1) == L')') ) { ClNetDbgPrint(( LOG_NOISE, "[ClNet] There may already be an instance number appended to '%1!ws!'\n", OldNetworkName )); // // Scan backwards looking for '(' // for (ptr = endPtr - 2, tempLength = 0; ptr != OldNetworkName; ptr--, tempLength++ ) { if (*ptr == L'(') { // // Looks promising. Check that all characters in between are // numbers and that the string size is reasonable. // if ((tempLength == 0) || (tempLength > 3)) { ClNetDbgPrint(( LOG_NOISE, "[ClNet] Unsure net name %'1!ws!' contains an instance number - ignore.\n", OldNetworkName )); break; } truncatePtr = ptr; for (ptr++; *ptr != L')'; ptr++) { if ( (*ptr < L'0') || (*ptr > L'9') ) { ClNetDbgPrint(( LOG_NOISE, "[ClNet] Tail of net name '%1!ws!' is not an instance number\n", OldNetworkName )); break; } } if (*ptr == L')') { // // This is an instance number. Truncate the string here. // ClNetDbgPrint(( LOG_NOISE, "[ClNet] Replacing old instance number '%1!ws!' appended to name '%2!ws!'\n", truncatePtr, OldNetworkName )); *truncatePtr = UNICODE_NULL; length -= tempLength + 2; } break; } } } // // Count number of digits in instance number // for (tempInstance = InstanceNumber; tempInstance > 0; tempInstance /= 10, length++ ); // // Account for '(', ')', and NULL // length += 3; newName = LocalAlloc(LMEM_FIXED, length * sizeof(WCHAR)); if (newName == NULL) { return(NULL); } wsprintfW(newName, L"%ws(%u)", OldNetworkName, InstanceNumber); ClNetDbgPrint(( LOG_NOISE, "[ClNet] New net name is '%1!ws!'\n", newName )); return(newName); } // ClNetpMakeNetworkName LPWSTR ClNetpMakeUniqueNetworkName( IN LPWSTR ConnectoidName, IN LPWSTR ConnectoidGuid, IN PCLNET_CONFIG_LISTS ConfigLists, IN PLIST_ENTRY UnchangedConfigList ) { BOOLEAN unique; BOOLEAN updateConnectoid = FALSE; LPWSTR newNetworkName; DWORD index = 1; newNetworkName = ClNetpCloneString(ConnectoidName); if (newNetworkName == NULL) { return(NULL); } do { unique = ClNetpIsNetworkNameUnique( newNetworkName, ConfigLists, UnchangedConfigList ); if (!unique) { LPWSTR oldNetworkName = newNetworkName; newNetworkName = ClNetpMakeNetworkName( oldNetworkName, index++ ); LocalFree(oldNetworkName); if (newNetworkName == NULL) { return(NULL); } updateConnectoid = TRUE; } } while (!unique); // // Update the local connectoid name if necessary. // if (updateConnectoid) { DWORD status; ClNetDbgPrint((LOG_UNUSUAL, "[ClNet] Changing name of connectoid '%1!ws!' to '%2!ws!' to " "guarantee cluster-wide uniqueness\n", ConnectoidName, newNetworkName )); status = ClRtlFindConnectoidByGuidAndSetName( ConnectoidGuid, newNetworkName ); if (status != ERROR_SUCCESS) { ClNetDbgPrint((LOG_UNUSUAL, "[ClNet] Failed to change name of connectoid '%1!ws!' to " "'%2!ws!', status %3!u!\n", ConnectoidName, newNetworkName, status )); } } return(newNetworkName); } // ClNetpMakeUniqueNetworkName DWORD ClNetpUpdateConfigEntry( PCLNET_CONFIG_ENTRY ConfigEntry, LPWSTR Address, LPWSTR AdapterId, LPWSTR AdapterName, LPWSTR NodeName, LPWSTR NetworkName ) { LPWSTR newAddress = NULL; LPWSTR newInterfaceName = NULL; LPWSTR newAdapterId = NULL; LPWSTR newAdapterName = NULL; if (Address != NULL) { newAddress = ClNetpCloneString(Address); if (newAddress == NULL) { goto error_exit; } } if (AdapterId != NULL) { newAdapterId = ClNetpCloneString(AdapterId); if (newAdapterId == NULL) { goto error_exit; } } if (AdapterName != NULL) { newAdapterName = ClNetpCloneString(AdapterName); if (newAdapterName == NULL) { goto error_exit; } } if ( (NodeName != NULL) && (NetworkName != NULL) ) { newInterfaceName = ClNetMakeInterfaceName( NULL, NodeName, NetworkName ); if (newInterfaceName == NULL) { goto error_exit; } } if (newAddress != NULL) { LocalFree(ConfigEntry->InterfaceInfo.Address); ConfigEntry->InterfaceInfo.Address = newAddress; } if (newAdapterId != NULL) { LocalFree(ConfigEntry->InterfaceInfo.AdapterId); ConfigEntry->InterfaceInfo.AdapterId = newAdapterId; } if (newAdapterName != NULL) { LocalFree(ConfigEntry->InterfaceInfo.AdapterName); ConfigEntry->InterfaceInfo.AdapterName = newAdapterName; } if (newInterfaceName != NULL) { LocalFree(ConfigEntry->InterfaceInfo.Name); ConfigEntry->InterfaceInfo.Name = newInterfaceName; } return(ERROR_SUCCESS); error_exit: if (newAddress != NULL) { LocalFree(newAddress); } if (newAdapterId != NULL) { LocalFree(newAdapterId); } if (newAdapterName != NULL) { LocalFree(newAdapterName); } if (newInterfaceName != NULL) { LocalFree(newInterfaceName); } return(ERROR_NOT_ENOUGH_MEMORY); } // ClNetpUpdateConfigEntry DWORD ClNetpAllocConfigEntryInterface( IN PCLNET_CONFIG_ENTRY ConfigEntry, IN LPWSTR InterfaceId, IN LPWSTR InterfaceName, IN LPWSTR InterfaceDescription, IN LPWSTR NodeId, IN LPWSTR AdapterId, IN LPWSTR AdapterName, IN LPWSTR InterfaceAddress, IN LPWSTR ClusnetEndpoint, IN DWORD InterfaceState ) { PNM_INTERFACE_INFO2 interfaceInfo = &(ConfigEntry->InterfaceInfo); if (InterfaceId != NULL) { interfaceInfo->Id = ClNetpCloneString(InterfaceId); if (interfaceInfo->Id == NULL) { goto error_exit; } } ConfigEntry->IsInterfaceInfoValid = TRUE; if (InterfaceName != NULL) { interfaceInfo->Name = ClNetpCloneString(InterfaceName); if (interfaceInfo->Name == NULL) { goto error_exit; } } if (InterfaceDescription != NULL) { interfaceInfo->Description = ClNetpCloneString(InterfaceDescription); if (interfaceInfo->Description == NULL) { goto error_exit; } } if (NodeId != NULL) { interfaceInfo->NodeId = ClNetpCloneString(NodeId); if (interfaceInfo->NodeId == NULL) { goto error_exit; } } interfaceInfo->NetworkId = ClNetpCloneString(ConfigEntry->NetworkInfo.Id); if (interfaceInfo->NetworkId == NULL) { goto error_exit; } if (AdapterId != NULL) { interfaceInfo->AdapterId = ClNetpCloneString(AdapterId); if (interfaceInfo->AdapterId == NULL) { goto error_exit; } } if (AdapterName != NULL) { interfaceInfo->AdapterName = ClNetpCloneString(AdapterName); if (interfaceInfo->AdapterName == NULL) { goto error_exit; } } if (InterfaceAddress != NULL) { interfaceInfo->Address = ClNetpCloneString(InterfaceAddress); if (interfaceInfo->Address == NULL) { goto error_exit; } } if (ClusnetEndpoint != NULL) { interfaceInfo->ClusnetEndpoint = ClNetpCloneString(ClusnetEndpoint); if (interfaceInfo->ClusnetEndpoint == NULL) { goto error_exit; } } interfaceInfo->State = InterfaceState; interfaceInfo->NetIndex = NmInvalidInterfaceNetIndex; return(ERROR_SUCCESS); error_exit: ClNetFreeInterfaceInfo(&(ConfigEntry->InterfaceInfo)); ConfigEntry->IsInterfaceInfoValid = FALSE; return(ERROR_NOT_ENOUGH_MEMORY); } // ClNetpAllocConfigEntryInterface DWORD ClNetpAllocConfigEntryNetwork( IN PCLNET_CONFIG_ENTRY ConfigEntry, IN LPWSTR NetworkId, IN LPWSTR NetworkName, IN LPWSTR NetworkDescription, IN DWORD NetworkRole, IN DWORD NetworkPriority, IN LPWSTR NetworkTransport, IN LPWSTR NetworkAddress, IN LPWSTR NetworkAddressMask ) { PNM_NETWORK_INFO networkInfo; networkInfo = &(ConfigEntry->NetworkInfo); if (NetworkId != NULL) { networkInfo->Id = ClNetpCloneString(NetworkId); if (networkInfo->Id == NULL) { goto error_exit; } } if (NetworkName != NULL) { networkInfo->Name = ClNetpCloneString(NetworkName); if (networkInfo->Name == NULL) { goto error_exit; } } if (NetworkDescription != NULL) { networkInfo->Description = ClNetpCloneString(NetworkDescription); if (networkInfo->Description == NULL) { goto error_exit; } } networkInfo->Role = NetworkRole; networkInfo->Priority = NetworkPriority; if (NetworkTransport != NULL) { networkInfo->Transport = ClNetpCloneString(NetworkTransport); if (networkInfo->Transport == NULL) { goto error_exit; } } if (NetworkAddress != NULL) { networkInfo->Address = ClNetpCloneString(NetworkAddress); if (networkInfo->Address == NULL) { goto error_exit; } } if (NetworkAddressMask != NULL) { networkInfo->AddressMask = ClNetpCloneString(NetworkAddressMask); if (networkInfo->AddressMask == NULL) { goto error_exit; } } return(ERROR_SUCCESS); error_exit: ClNetFreeConfigEntry(ConfigEntry); return(ERROR_NOT_ENOUGH_MEMORY); } // ClNetpAllocConfigEntryNetwork DWORD ClNetpCreateConfigEntryInterface( PCLNET_CONFIG_ENTRY ConfigEntry, LPWSTR NodeName, LPWSTR NodeId, PCLRTL_NET_ADAPTER_INFO AdapterInfo, PCLRTL_NET_INTERFACE_INFO AdapterIfInfo, LPWSTR ClusnetEndpoint ) { LPWSTR id; LPWSTR name; DWORD status = ERROR_NOT_ENOUGH_MEMORY; id = ClRtlMakeGuid(); if (id != NULL) { name = ClNetMakeInterfaceName( NULL, NodeName, ConfigEntry->NetworkInfo.Name ); if (name != NULL) { status = ClNetpAllocConfigEntryInterface( ConfigEntry, NULL, // Id NULL, // Name ClNetpEmptyString, // Description NodeId, AdapterInfo->DeviceGuid, AdapterInfo->DeviceName, AdapterIfInfo->InterfaceAddressString, ClusnetEndpoint, ClusterNetInterfaceUnavailable ); if (status == ERROR_SUCCESS) { ConfigEntry->InterfaceInfo.Id = id; ConfigEntry->InterfaceInfo.Name = name; return(ERROR_SUCCESS); } LocalFree(name); } LocalFree(id); } return(status); } // ClNetpCreateInterface PCLNET_CONFIG_ENTRY ClNetpCreateConfigEntry( LPWSTR NodeName, LPWSTR NodeId, LPWSTR NetworkName, DWORD NetworkRole, DWORD NetworkPriority, PCLRTL_NET_ADAPTER_INFO AdapterInfo, PCLRTL_NET_INTERFACE_INFO AdapterIfInfo, LPWSTR ClusnetEndpoint ) { PCLNET_CONFIG_ENTRY newEntry; DWORD status; newEntry = LocalAlloc( (LMEM_FIXED | LMEM_ZEROINIT), sizeof(CLNET_CONFIG_ENTRY) ); if (newEntry == NULL) { return(NULL); } newEntry->NetworkInfo.Id = ClRtlMakeGuid(); if (newEntry->NetworkInfo.Id == NULL) { goto error_exit; } newEntry->NetworkInfo.Name = ClNetpCloneString(NetworkName); if (newEntry->NetworkInfo.Name == NULL) { goto error_exit; } status = ClNetpCreateConfigEntryInterface( newEntry, NodeName, NodeId, AdapterInfo, AdapterIfInfo, ClusnetEndpoint ); if (status != ERROR_SUCCESS) { goto error_exit; } status = ClNetpAllocConfigEntryNetwork( newEntry, NULL, // NetworkId NULL, // NetworkName ClNetpEmptyString, // Description NetworkRole, NetworkPriority, L"Tcpip", AdapterIfInfo->NetworkAddressString, AdapterIfInfo->NetworkMaskString ); if (status == ERROR_SUCCESS) { return(newEntry); } error_exit: ClNetFreeConfigEntry(newEntry); LocalFree(newEntry); return(NULL); } // ClNetpCreateConfigEntry DWORD ClNetpCopyNetworkInfo( IN PNM_NETWORK_INFO DstInfo, IN PNM_NETWORK_INFO SrcInfo ) { DWORD status = ERROR_SUCCESS; try { DstInfo->Id = ClNetCopyString(SrcInfo->Id, TRUE); DstInfo->Name = ClNetCopyString(SrcInfo->Name, TRUE); DstInfo->Description = ClNetCopyString(SrcInfo->Description, TRUE); DstInfo->Role = SrcInfo->Role; DstInfo->Priority = SrcInfo->Priority; DstInfo->Transport = ClNetCopyString(SrcInfo->Transport, TRUE); DstInfo->Address = ClNetCopyString(SrcInfo->Address, TRUE); DstInfo->AddressMask = ClNetCopyString(SrcInfo->AddressMask, TRUE); DstInfo->Ignore = FALSE; } except (EXCEPTION_EXECUTE_HANDLER) { status = GetExceptionCode(); ClNetFreeNetworkInfo(DstInfo); } return(status); } // ClNetpCopyNetworkInfo DWORD ClNetpCopyInterfaceInfo( IN PNM_INTERFACE_INFO2 DstInfo, IN PNM_INTERFACE_INFO2 SrcInfo ) { DWORD status = ERROR_SUCCESS; try { DstInfo->Id = ClNetCopyString(SrcInfo->Id, TRUE); DstInfo->Name = ClNetCopyString(SrcInfo->Name, TRUE); DstInfo->Description = ClNetCopyString(SrcInfo->Description, TRUE); DstInfo->NodeId = ClNetCopyString(SrcInfo->NodeId, TRUE); DstInfo->NetworkId = ClNetCopyString(SrcInfo->NetworkId, TRUE); DstInfo->AdapterName = ClNetCopyString(SrcInfo->AdapterName, TRUE); DstInfo->Address = ClNetCopyString(SrcInfo->Address, TRUE); DstInfo->ClusnetEndpoint = ClNetCopyString( SrcInfo->ClusnetEndpoint, TRUE ); DstInfo->State = SrcInfo->State; DstInfo->Ignore = FALSE; DstInfo->AdapterId = ClNetCopyString(SrcInfo->AdapterId, TRUE); DstInfo->NetIndex = SrcInfo->NetIndex; } except (EXCEPTION_EXECUTE_HANDLER) { status = GetExceptionCode(); ClNetFreeInterfaceInfo(DstInfo); } return(status); } // ClNetpCopyInterfaceInfo ////////////////////////////////////////////////////////////////////////////// // // Public routines // ////////////////////////////////////////////////////////////////////////////// VOID ClNetInitialize( IN LPFN_CLNETPRINT pfnPrint, IN LPFN_CLNETLOGEVENT pfnLogEvent, IN LPFN_CLNETLOGEVENT1 pfnLogEvent1, IN LPFN_CLNETLOGEVENT2 pfnLogEvent2, IN LPFN_CLNETLOGEVENT3 pfnLogEvent3 ) { pClNetPrint = pfnPrint; pClNetLogEvent = pfnLogEvent; pClNetLogEvent1 = pfnLogEvent1; pClNetLogEvent2 = pfnLogEvent2; pClNetLogEvent3 = pfnLogEvent3; } // ClNetInitialize LPWSTR ClNetCopyString( IN LPWSTR SourceString, IN BOOL RaiseExceptionOnError ) { LPWSTR str; str = (LPWSTR) MIDL_user_allocate( (lstrlenW(SourceString) + 1) * sizeof(WCHAR) ); if (str != NULL) { lstrcpyW(str, SourceString); } else if (RaiseExceptionOnError) { RaiseException(ERROR_NOT_ENOUGH_MEMORY, 0, 0, NULL); } return(str); } // ClNetCopyString VOID ClNetInitializeConfigLists( PCLNET_CONFIG_LISTS Lists ) { InitializeListHead(&(Lists->InputConfigList)); InitializeListHead(&(Lists->DeletedInterfaceList)); InitializeListHead(&(Lists->UpdatedInterfaceList)); InitializeListHead(&(Lists->CreatedInterfaceList)); InitializeListHead(&(Lists->CreatedNetworkList)); return; } // ClNetInitializeConfigLists DWORD ClNetConvertEnumsToConfigList( IN PNM_NETWORK_ENUM * NetworkEnum, IN PNM_INTERFACE_ENUM2 * InterfaceEnum, IN LPWSTR LocalNodeId, IN OUT PLIST_ENTRY ConfigList, IN BOOLEAN DeleteEnums ) { DWORD i, j; DWORD status; PNM_NETWORK_INFO network; PNM_INTERFACE_INFO2 netInterface; PCLNET_CONFIG_ENTRY configEntry; InitializeListHead(ConfigList); for (i=0; i<(*NetworkEnum)->NetworkCount; i++) { network = &((*NetworkEnum)->NetworkList[i]); configEntry = LocalAlloc( (LMEM_FIXED | LMEM_ZEROINIT), sizeof(CLNET_CONFIG_ENTRY) ); if (configEntry == NULL) { status = ERROR_NOT_ENOUGH_MEMORY; goto error_exit; } if (DeleteEnums) { CopyMemory( &(configEntry->NetworkInfo), network, sizeof(NM_NETWORK_INFO) ); } else { status = ClNetpCopyNetworkInfo( &(configEntry->NetworkInfo), network ); if (status != ERROR_SUCCESS) { goto error_exit; } } for (j=0; j<(*InterfaceEnum)->InterfaceCount; j++) { netInterface = &((*InterfaceEnum)->InterfaceList[j]); if ( (netInterface->Ignore == FALSE) && (lstrcmpiW(netInterface->NetworkId, network->Id) == 0) && (lstrcmpiW(netInterface->NodeId, LocalNodeId) == 0) ) { if (DeleteEnums) { CopyMemory( &(configEntry->InterfaceInfo), netInterface, sizeof(NM_INTERFACE_INFO2) ); } else { status = ClNetpCopyInterfaceInfo( &(configEntry->InterfaceInfo), netInterface ); if (status != ERROR_SUCCESS) { goto error_exit; } } configEntry->IsInterfaceInfoValid = TRUE; if ( DeleteEnums ) { ZeroMemory(netInterface, sizeof(NM_INTERFACE_INFO2)); } netInterface->Ignore = TRUE; break; } } InsertTailList(ConfigList, &(configEntry->Linkage)); if ( DeleteEnums ) { ZeroMemory(network, sizeof(NM_NETWORK_INFO)); } } status = ERROR_SUCCESS; error_exit: if ( DeleteEnums ) { ClNetFreeNetworkEnum(*NetworkEnum); *NetworkEnum = NULL; ClNetFreeInterfaceEnum(*InterfaceEnum); *InterfaceEnum = NULL; } if (status != ERROR_SUCCESS) { ClNetFreeConfigList(ConfigList); } return(status); } // ClNetConvertEnumsToConfigList VOID ClNetFreeNetworkEnum( IN PNM_NETWORK_ENUM NetworkEnum ) /*++ Routine Description: Frees a network enumeration structure. Arguments: NetworkEnum - A pointer to the network enumeration structure to free. Return Value: None. --*/ { DWORD i; for (i=0; iNetworkCount; i++) { ClNetFreeNetworkInfo(&(NetworkEnum->NetworkList[i])); } MIDL_user_free(NetworkEnum); return; } // ClNetFreeNetworkEnum VOID ClNetFreeNetworkInfo( IN PNM_NETWORK_INFO NetworkInfo ) /*++ Routine Description: Frees a network information structure or a linked list of network information structures. Arguments: NetworkInfo - A pointer to the network information structure to free. Return Value: None. --*/ { if (NetworkInfo->Id != NULL) { MIDL_user_free(NetworkInfo->Id); NetworkInfo->Id = NULL; } if (NetworkInfo->Name != NULL) { MIDL_user_free(NetworkInfo->Name); NetworkInfo->Name = NULL; } if (NetworkInfo->Description != NULL) { MIDL_user_free(NetworkInfo->Description); NetworkInfo->Description = NULL; } if (NetworkInfo->Transport != NULL) { MIDL_user_free(NetworkInfo->Transport); NetworkInfo->Transport = NULL; } if (NetworkInfo->Address != NULL) { MIDL_user_free(NetworkInfo->Address); NetworkInfo->Address = NULL; } if (NetworkInfo->AddressMask != NULL) { MIDL_user_free(NetworkInfo->AddressMask); NetworkInfo->AddressMask = NULL; } return; } // ClNetFreeNetworkInfo VOID ClNetFreeInterfaceEnum1( IN PNM_INTERFACE_ENUM InterfaceEnum1 ) /*++ Routine Description: Frees a interface enumeration structure. Arguments: InterfaceEnum - A pointer to the interface enumeration structure to free. Return Value: None. --*/ { DWORD i; for (i=0; iInterfaceCount; i++) { ClNetFreeInterfaceInfo( (PNM_INTERFACE_INFO2) &(InterfaceEnum1->InterfaceList[i]) ); } MIDL_user_free(InterfaceEnum1); return; } // ClNetFreeInterfaceEnum VOID ClNetFreeInterfaceEnum( IN PNM_INTERFACE_ENUM2 InterfaceEnum ) /*++ Routine Description: Frees a interface enumeration structure. Arguments: InterfaceEnum - A pointer to the interface enumeration structure to free. Return Value: None. --*/ { DWORD i; for (i=0; iInterfaceCount; i++) { ClNetFreeInterfaceInfo(&(InterfaceEnum->InterfaceList[i])); } MIDL_user_free(InterfaceEnum); return; } // ClNetFreeInterfaceEnum VOID ClNetFreeInterfaceInfo( IN PNM_INTERFACE_INFO2 InterfaceInfo ) /*++ Routine Description: Frees a network interface information strucuture. Arguments: InterfaceInfo - A pointer to the interface information structure to free. Return Value: None. --*/ { if (InterfaceInfo->Id != NULL) { MIDL_user_free(InterfaceInfo->Id); InterfaceInfo->Id = NULL; } if (InterfaceInfo->Name != NULL) { MIDL_user_free(InterfaceInfo->Name); InterfaceInfo->Name = NULL; } if (InterfaceInfo->Description != NULL) { MIDL_user_free(InterfaceInfo->Description); InterfaceInfo->Description = NULL; } if (InterfaceInfo->NetworkId != NULL) { MIDL_user_free(InterfaceInfo->NetworkId); InterfaceInfo->NetworkId = NULL; } if (InterfaceInfo->NodeId != NULL) { MIDL_user_free(InterfaceInfo->NodeId); InterfaceInfo->NodeId = NULL; } if (InterfaceInfo->AdapterId != NULL) { MIDL_user_free(InterfaceInfo->AdapterId); InterfaceInfo->AdapterId = NULL; } if (InterfaceInfo->AdapterName != NULL) { MIDL_user_free(InterfaceInfo->AdapterName); InterfaceInfo->AdapterName = NULL; } if (InterfaceInfo->Address != NULL) { MIDL_user_free(InterfaceInfo->Address); InterfaceInfo->Address = NULL; } if (InterfaceInfo->ClusnetEndpoint != NULL) { MIDL_user_free(InterfaceInfo->ClusnetEndpoint); InterfaceInfo->ClusnetEndpoint = NULL; } return; } // ClNetFreeInterfaceInfo VOID ClNetFreeNodeEnum1( IN PNM_NODE_ENUM NodeEnum1 ) /*++ Routine Description: Frees a node enumeration structure. Arguments: NodeEnum - A pointer to the node enumeration structure to free. Return Value: None. --*/ { DWORD i; for (i=0; iNodeCount; i++) { ClNetFreeNodeInfo( (PNM_NODE_INFO2) &(NodeEnum1->NodeList[i]) ); } MIDL_user_free(NodeEnum1); return; } // NmpFreeNodeEnum1 VOID ClNetFreeNodeEnum( IN PNM_NODE_ENUM2 NodeEnum ) /*++ Routine Description: Frees a node enumeration structure. Arguments: NodeEnum - A pointer to the node enumeration structure to free. Return Value: None. --*/ { DWORD i; for (i=0; iNodeCount; i++) { ClNetFreeNodeInfo(&(NodeEnum->NodeList[i])); } MIDL_user_free(NodeEnum); return; } // NmpFreeNodeEnum VOID ClNetFreeNodeInfo( IN PNM_NODE_INFO2 NodeInfo ) /*++ Routine Description: Frees a node information structure. Arguments: NodeInfo - A pointer to the node information structure to free. Return Value: None. --*/ { // // Currently nothing to free. // return; } // NmpFreeNodeInfo VOID ClNetFreeConfigEntry( PCLNET_CONFIG_ENTRY ConfigEntry ) { ClNetFreeNetworkInfo(&(ConfigEntry->NetworkInfo)); if (ConfigEntry->IsInterfaceInfoValid) { ClNetFreeInterfaceInfo(&(ConfigEntry->InterfaceInfo)); } return; } // ClNetFreeConfigEntry VOID ClNetFreeConfigList( IN PLIST_ENTRY ConfigList ) { PLIST_ENTRY listEntry; PCLNET_CONFIG_ENTRY configEntry; while (!IsListEmpty(ConfigList)) { listEntry = RemoveHeadList(ConfigList); configEntry = CONTAINING_RECORD( listEntry, CLNET_CONFIG_ENTRY, Linkage ); ClNetFreeConfigEntry(configEntry); } return; } // ClNetFreeConfigList VOID ClNetFreeConfigLists( PCLNET_CONFIG_LISTS ConfigLists ) { ClNetFreeConfigList(&(ConfigLists->InputConfigList)); ClNetFreeConfigList(&(ConfigLists->DeletedInterfaceList)); ClNetFreeConfigList(&(ConfigLists->UpdatedInterfaceList)); ClNetFreeConfigList(&(ConfigLists->CreatedInterfaceList)); ClNetFreeConfigList(&(ConfigLists->CreatedNetworkList)); return; } // ClNetFreeConfigLists LPWSTR ClNetMakeInterfaceName( LPWSTR Prefix, OPTIONAL LPWSTR NodeName, LPWSTR NetworkName ) /*++ Construct a name of the form " - ". Code in cluscfg.exe depends on this form. If you change this, you need to change the code in setup\cluscfg\netadptr.cpp as well --*/ { WCHAR text[] = L" - "; LPWSTR name; DWORD nameLength = 0; if (Prefix != NULL) { nameLength += lstrlenW(Prefix); } nameLength += lstrlenW(text) + lstrlenW(NodeName) + lstrlenW(NetworkName) + 1; nameLength *= sizeof(WCHAR); name = MIDL_user_allocate(nameLength); if (name != NULL) { name[0] = UNICODE_NULL; if (Prefix != NULL) { lstrcatW(name, Prefix); } lstrcatW(name, NetworkName); lstrcatW(name, text); lstrcatW(name, NodeName); return(name); } SetLastError(ERROR_NOT_ENOUGH_MEMORY); return(NULL); } // ClNetMakeInterfaceName DWORD ClNetConfigureNetworks( IN LPWSTR LocalNodeId, IN LPWSTR LocalNodeName, IN LPWSTR DefaultClusnetEndpoint, IN CLUSTER_NETWORK_ROLE DefaultNetworkRole, IN BOOL NetNameHasPrecedence, IN OUT PCLNET_CONFIG_LISTS ConfigLists, IN OUT LPDWORD MatchedNetworkCount, IN OUT LPDWORD NewNetworkCount ) /*++ Notes: NetNameHasPrecedence is TRUE if connectoid names should be changed to align with the name in the NM_NETWORK_INFO struct. Otherwise the name of network object is changed to match the connectoid name. Output interface lists must be processed in the following order to guarantee correctness: 1 - DeletedInterfaceList 2 - UpdatedInterfaceList 3 - CreatedInterfaceList 4 - CreatedNetworkList --*/ { DWORD status = ERROR_SUCCESS; PCLRTL_NET_ADAPTER_ENUM adapterEnum = NULL; PCLRTL_NET_ADAPTER_INFO adapterInfo = NULL; PCLRTL_NET_INTERFACE_INFO adapterIfInfo = NULL; WCHAR errorString[12]; DWORD eventCode = 0; DWORD hiddenAdapterCount = 0; PLIST_ENTRY listEntry; PCLNET_CONFIG_ENTRY configEntry; PNM_NETWORK_INFO networkInfo; PNM_INTERFACE_INFO2 interfaceInfo; LIST_ENTRY unchangedConfigList; DWORD matchedNetworkCount = 0; DWORD newNetworkCount = 0; BOOLEAN newAdapter; ClNetDbgPrint((LOG_NOISE, "[ClNet] Configuring networks...\n")); if (NetNameHasPrecedence) { ClNetDbgPrint(( LOG_NOISE, "[ClNet] Cluster network names have precedence over " "local connection object names.\n" )); } else { ClNetDbgPrint(( LOG_NOISE, "[ClNet] Local connection object names have precedence " "over cluster network names.\n" )); } InitializeListHead(&unchangedConfigList); // // Obtain the network configuration for the local system. // ClNetDbgPrint(( LOG_NOISE, "[ClNet] Querying local network configuration.\n" )); adapterEnum = ClRtlEnumNetAdapters(); if (adapterEnum == NULL) { status = GetLastError(); wsprintfW(&(errorString[0]), L"%u", status); (*pClNetLogEvent1)( LOG_CRITICAL, CLNET_EVENT_QUERY_CONFIG_FAILED, errorString ); ClNetDbgPrint(( LOG_CRITICAL, "[ClNet] Failed to obtain local system network config, " "status %1!u!.\n", status )); return(status); } // // Ignore all adapters which are hidden or have an address of 0.0.0.0. // for (adapterInfo = adapterEnum->AdapterList; adapterInfo != NULL; adapterInfo = adapterInfo->Next ) { if (adapterInfo->Flags & CLRTL_NET_ADAPTER_HIDDEN) { ClNetDbgPrint(( LOG_NOISE, "[ClNet] Ignoring hidden adapter '%1!ws!' (%2!ws!).\n", adapterInfo->DeviceName, adapterInfo->DeviceGuid )); adapterInfo->Ignore = TRUE; hiddenAdapterCount++; } else { adapterIfInfo = ClRtlGetPrimaryNetInterface(adapterInfo); if (adapterIfInfo != NULL) { if (adapterIfInfo->InterfaceAddress == 0) { (*pClNetLogEvent1)( LOG_UNUSUAL, CLNET_EVENT_INVALID_ADAPTER_ADDRESS, adapterInfo->DeviceName ); ClNetDbgPrint(( LOG_NOISE, "[ClNet] Ignoring adapter '%1!ws!' " "(%2!ws!) because its" "primary address is 0.0.0.0.\n", adapterInfo->DeviceName, adapterInfo->DeviceGuid )); adapterInfo->Ignore = TRUE; hiddenAdapterCount++; } } else { ClNetDbgPrint(( LOG_NOISE, "[ClNet] Ignoring adapter '%1!ws!' " "(%2!ws!) because its primary net " "interface could not be found.\n", adapterInfo->DeviceName, adapterInfo->DeviceGuid )); adapterInfo->Ignore = TRUE; hiddenAdapterCount++; } } } if ((adapterEnum->AdapterCount - hiddenAdapterCount) == 0) { (*pClNetLogEvent)( LOG_UNUSUAL, CLNET_EVENT_NO_VALID_ADAPTER ); ClNetDbgPrint(( LOG_CRITICAL, "[ClNet] No usable network adapters are installed in this " "system.\n" )); } // // Phase 1 // // Validate existing interface definitions for this node // and update as needed. // ClNetDbgPrint(( LOG_NOISE, "[ClNet] Phase 1 - Examining previous network definitions.\n" )); // // Walk all of the network definitions and examine the corresponding // interface definitions for this node. // while (!IsListEmpty(&(ConfigLists->InputConfigList))) { configEntry = CONTAINING_RECORD( ConfigLists->InputConfigList.Flink, CLNET_CONFIG_ENTRY, Linkage ); networkInfo = &(configEntry->NetworkInfo); ClNetDbgPrint(( LOG_NOISE, "[ClNet] Examining cluster network '%1!ws!' (%2!ws!).\n", networkInfo->Name, networkInfo->Id )); // // Check if there is an existing interface definition for // this node on this network. // if (configEntry->IsInterfaceInfoValid) { // An interface definition already exists for this node on // the network. We will either find an installed adapter for it // or delete the interface. // interfaceInfo = &(configEntry->InterfaceInfo); ClNetDbgPrint(( LOG_NOISE, "[ClNet] This node was attached to the network by " "adapter '%1!ws!', (%2!ws!).\n", interfaceInfo->AdapterName, interfaceInfo->AdapterId )); // // Try to find the adapter specified in the interface // definition. If it is still attached to the network, // then we want to reuse it. // ClNetDbgPrint(( LOG_NOISE, "[ClNet] Checking if adapter '%1!ws!' is still installed.\n", interfaceInfo->AdapterName )); adapterInfo = ClRtlFindNetAdapterById( adapterEnum, interfaceInfo->AdapterId ); if (adapterInfo != NULL) { // // Found the specified adapter. Check if this // adapter is still attached to the network by // comparing network address values. // ClNetDbgPrint(( LOG_NOISE, "[ClNet] Adapter '%1!ws!' is still installed, checking " "if it is still attached to the same network.\n", adapterInfo->DeviceName )); adapterIfInfo = ClRtlFindNetInterfaceByNetworkAddress( adapterInfo, networkInfo->Address ); if (adapterIfInfo != NULL) { // // The adapter is still attached to this network. // newAdapter = FALSE; ClNetDbgPrint(( LOG_NOISE, "[ClNet] Adapter '%1!ws!' is still attached to " "network %2!ws!.\n", interfaceInfo->AdapterName, networkInfo->Name )); } else { // // The adapter is no longer attached to this network. // adapterInfo = NULL; ClNetDbgPrint(( LOG_NOISE, "[ClNet] Adapter '%1!ws!' is no longer attached " "to network %2!ws!.\n", interfaceInfo->AdapterName, networkInfo->Name )); } } else { ClNetDbgPrint(( LOG_NOISE, "[ClNet] Adapter '%1!ws!' is no longer available.\n", interfaceInfo->AdapterName )); } // // If the old adapter was removed or is now attached to a // different network, search for a new adapter that is // attached to the network. // if (adapterInfo == NULL) { ClNetDbgPrint(( LOG_NOISE, "[ClNet] Searching for a new adapter which is attached " "to network '%1!ws!'.\n", networkInfo->Name )); adapterIfInfo = NULL; adapterInfo = ClRtlFindNetAdapterByNetworkAddress( adapterEnum, networkInfo->Address, &adapterIfInfo ); if (adapterInfo != NULL) { ClNetDbgPrint(( LOG_NOISE, "[ClNet] Adapter '%1!ws!' (%2!ws!) is attached to " "network '%3!ws!'.\n", interfaceInfo->AdapterName, interfaceInfo->AdapterId, networkInfo->Name )); newAdapter = TRUE; } } // // If we found an adapter, old or new, which is attached to this // network, update the interface definition, as needed. // if (adapterInfo != NULL) { BOOLEAN somethingChanged = FALSE; BOOL netNameHasPrecedence = NetNameHasPrecedence; LPWSTR address = NULL; LPWSTR adapterName = NULL; LPWSTR adapterId = NULL; LPWSTR networkName = NULL; if (newAdapter) { netNameHasPrecedence = TRUE; adapterId = adapterInfo->DeviceGuid; somethingChanged = TRUE; } // // If the address value has changed, update it // if (lstrcmpW( interfaceInfo->Address, adapterIfInfo->InterfaceAddressString ) != 0 ) { ClNetDbgPrint(( LOG_NOISE, "[ClNet] The address for the network interface has " "changed to %1!ws!.\n", adapterIfInfo->InterfaceAddressString )); address = adapterIfInfo->InterfaceAddressString; somethingChanged = TRUE; } // // If the adapter name changed, update it. // if (lstrcmpW( interfaceInfo->AdapterName, adapterInfo->DeviceName ) != 0 ) { if (!newAdapter) { ClNetDbgPrint(( LOG_NOISE, "[ClNet] The adapter name for the network " "interface has changed to '%1!ws!'.\n", adapterInfo->DeviceName )); } adapterName = adapterInfo->DeviceName; somethingChanged = TRUE; } // // If the connectoid name is different, choose the correct // name based on the name precedence and update the // network, connectoid, and interface names as // appropriate. // if (lstrcmpW( networkInfo->Name, adapterInfo->ConnectoidName ) != 0 ) { if (netNameHasPrecedence) { // // Update the local connectoid name. // DWORD status; ClNetDbgPrint((LOG_NOISE, "[ClNet] Changing name of connectoid '%1!ws!' " "(%2!ws!) to match name of cluster " "network '%3!ws'\n", adapterInfo->ConnectoidName, adapterInfo->DeviceGuid, networkInfo->Name )); status = ClRtlFindConnectoidByGuidAndSetName( adapterInfo->DeviceGuid, networkInfo->Name ); if ( status != ERROR_SUCCESS ) { ClNetDbgPrint((LOG_UNUSUAL, "[ClNet] Failed to change name of " "connectoid from '%1!ws!' to '%2!ws!', " "status %3!u!\n", adapterInfo->ConnectoidName, networkInfo->Name, status )); } } else { // // Update the network name. The connectoid name // may get tweaked for uniqueness as a side // effect. // ClNetDbgPrint((LOG_UNUSUAL, "[ClNet] Changing name of cluster " "network '%1!ws!' (%2!ws!) to match name of " "connectoid '%3!ws!'.\n", networkInfo->Name, networkInfo->Id, adapterInfo->ConnectoidName )); networkName = ClNetpMakeUniqueNetworkName( adapterInfo->ConnectoidName, adapterInfo->DeviceGuid, ConfigLists, &unchangedConfigList ); if (networkName == NULL) { status = ERROR_NOT_ENOUGH_MEMORY; goto error_exit; } ClNetDbgPrint(( LOG_NOISE, "[ClNet] Changed name of cluster " "network '%1!ws!' (%2!ws!) to '%3!ws!'.\n", networkInfo->Name, networkInfo->Id, networkName )); LocalFree(networkInfo->Name); networkInfo->Name = networkName; configEntry->UpdateNetworkName = TRUE; somethingChanged = TRUE; } } if (somethingChanged) { ClNetDbgPrint(( LOG_NOISE, "[ClNet] Updating configuration info for " "interface '%1!ws!' (%2!ws!).\n", interfaceInfo->Name, interfaceInfo->Id )); status = ClNetpUpdateConfigEntry( configEntry, address, adapterId, adapterName, LocalNodeName, networkName ); if (status != ERROR_SUCCESS) { goto error_exit; } // // Move the entry to the updated interface list // RemoveEntryList(&(configEntry->Linkage)); InsertTailList( &(ConfigLists->UpdatedInterfaceList), &(configEntry->Linkage) ); } else { // // Move the entry to the unchanged list // RemoveEntryList(&(configEntry->Linkage)); InsertTailList( &unchangedConfigList, &(configEntry->Linkage) ); } } else { // // This node is no longer attached to this network. // ClNetDbgPrint(( LOG_NOISE, "[ClNet] This node is no longer attached to " "network '%1!ws!' (%2!ws!).\n", networkInfo->Name, networkInfo->Id )); (*pClNetLogEvent3)( LOG_NOISE, CLNET_EVENT_DELETE_INTERFACE, networkInfo->Name, interfaceInfo->AdapterName, interfaceInfo->Name ); ClNetDbgPrint(( LOG_NOISE, "[ClNet] Deleting interface '%1!ws!' (%2!ws!) from the " "cluster configuration.\n", interfaceInfo->Name, interfaceInfo->Id )); // // Move the entry to the deleted interface list. // RemoveEntryList(&(configEntry->Linkage)); InsertTailList( &(ConfigLists->DeletedInterfaceList), &(configEntry->Linkage) ); } } else { // // This node was not previously attached to this network. // Search for a new attachment. // ClNetDbgPrint(( LOG_NOISE, "[ClNet] This node was not previously attached to " "network '%1!ws!' (%2!ws!).\n", networkInfo->Name, networkInfo->Id )); ClNetDbgPrint(( LOG_NOISE, "[ClNet] Searching for a new attachment...\n" )); adapterInfo = ClRtlFindNetAdapterByNetworkAddress( adapterEnum, networkInfo->Address, &adapterIfInfo ); if (adapterInfo != NULL) { // // Found a new adapter which is attached to this network. // Create a new interface definition for it. // ClNetDbgPrint(( LOG_NOISE, "[ClNet] Adapter '%1!ws!' (%2!ws!) is attached to " "network %3!ws!.\n", adapterInfo->DeviceName, adapterInfo->DeviceGuid, networkInfo->Name )); // // Network name has precedence. // Update the local connectoid name if necessary. // if (lstrcmpW( networkInfo->Name, adapterInfo->ConnectoidName ) != 0 ) { DWORD status; ClNetDbgPrint((LOG_NOISE, "[ClNet] Changing name of connectoid '%1!ws!' (%2!ws!) " "to match name of cluster network '%3!ws!'\n", adapterInfo->ConnectoidName, adapterInfo->DeviceGuid, networkInfo->Name )); status = ClRtlFindConnectoidByGuidAndSetName( adapterInfo->DeviceGuid, networkInfo->Name ); if ( status != ERROR_SUCCESS ) { ClNetDbgPrint(( LOG_UNUSUAL, "[ClNet] Failed to change name of connectoid " "'%1!ws!' (%2!ws!) to '%3!ws!', status %4!u!.\n", adapterInfo->ConnectoidName, adapterInfo->DeviceGuid, networkInfo->Name, status )); } } status = ClNetpCreateConfigEntryInterface( configEntry, LocalNodeName, LocalNodeId, adapterInfo, adapterIfInfo, DefaultClusnetEndpoint ); if (status != ERROR_SUCCESS) { goto error_exit; } ClNetDbgPrint(( LOG_NOISE, "[ClNet] Created cluster interface '%1!ws!' (%2!ws!).\n", configEntry->InterfaceInfo.Name, configEntry->InterfaceInfo.Id )); // // Put the entry on the created interface list // RemoveEntryList(&(configEntry->Linkage)); InsertTailList( &(ConfigLists->CreatedInterfaceList), &(configEntry->Linkage) ); } else { ClNetDbgPrint(( LOG_NOISE, "[ClNet] This node is not attached to network '%1!ws!'.\n", networkInfo->Name )); // // Move the entry to the unchanged list // RemoveEntryList(&(configEntry->Linkage)); InsertTailList(&unchangedConfigList, &(configEntry->Linkage)); } } // // If we found an adapter on this network, then mark it as // consumed. // if (adapterInfo != NULL) { // // Consume the adapter adapterInfo->Ignore = TRUE; // // // Consume all other adapters that are attached to this // network // ClNetpConsumeAdaptersOnNetwork( adapterEnum, adapterIfInfo->NetworkAddressString ); matchedNetworkCount++; } } // // Phase 2 // // Create new networks for any remaining adapters. // ClNetDbgPrint(( LOG_NOISE, "[ClNet] Phase 2 - Creating new networks for all remaining " "adapters.\n" )); for (adapterInfo = adapterEnum->AdapterList; adapterInfo != NULL; adapterInfo = adapterInfo->Next ) { if ( !adapterInfo->Ignore && (adapterInfo->InterfaceCount > 0) ) { LPWSTR newNetworkName; (*pClNetLogEvent1)( LOG_NOISE, CLNET_EVENT_CREATE_NETWORK, adapterInfo->ConnectoidName ); ClNetDbgPrint(( LOG_NOISE, "[ClNet] Creating new network & interface for " "adapter '%1!ws!'.\n", adapterInfo->DeviceName )); // // Create a unique network name based on the connectoid name. // The connectoid name may get tweaked for uniqueness as a // side effect. // newNetworkName = ClNetpMakeUniqueNetworkName( adapterInfo->ConnectoidName, adapterInfo->DeviceGuid, ConfigLists, &unchangedConfigList ); if (newNetworkName == NULL) { status = ERROR_NOT_ENOUGH_MEMORY; goto error_exit; } adapterIfInfo = ClRtlGetPrimaryNetInterface(adapterInfo); if (adapterIfInfo == NULL) { ClNetDbgPrint(( LOG_NOISE, "[ClNet] Not creating network for adapter " " '%1!ws!' (%2!ws!) because its primary net " "interface could not be found.\n", adapterInfo->DeviceName, adapterInfo->DeviceGuid )); LocalFree(newNetworkName); goto error_exit; } configEntry = ClNetpCreateConfigEntry( LocalNodeName, LocalNodeId, newNetworkName, DefaultNetworkRole, CLNET_DEFAULT_NETWORK_PRIORITY, adapterInfo, adapterIfInfo, DefaultClusnetEndpoint ); LocalFree(newNetworkName); if (configEntry == NULL) { ClNetDbgPrint(( LOG_NOISE, "[ClNet] Failed to create new network & interface " "for adapter '%1!ws!' (%2!ws!)\n", adapterInfo->DeviceName, adapterInfo->DeviceGuid )); goto error_exit; } ClNetDbgPrint(( LOG_NOISE, "[ClNet] Created interface '%1!ws!' (%2!ws!).\n", configEntry->InterfaceInfo.Name, configEntry->InterfaceInfo.Id )); ClNetDbgPrint(( LOG_NOISE, "[ClNet] Created network '%1!ws!' (%2!ws!).\n", configEntry->NetworkInfo.Name, configEntry->NetworkInfo.Id )); InsertTailList( &(ConfigLists->CreatedNetworkList), &(configEntry->Linkage) ); // // Consume the adapter adapterInfo->Ignore = TRUE; // // // Consume all other adapters that are attached to this // network // ClNetpConsumeAdaptersOnNetwork( adapterEnum, adapterIfInfo->NetworkAddressString ); newNetworkCount++; } } status = ERROR_SUCCESS; *MatchedNetworkCount = matchedNetworkCount; *NewNetworkCount = newNetworkCount; error_exit: // // Move unchanged entries back to the input list. // while (!IsListEmpty(&unchangedConfigList)) { listEntry = RemoveHeadList(&(unchangedConfigList)); InsertTailList(&(ConfigLists->InputConfigList), listEntry); } // // Free the adapter resources // if (adapterEnum != NULL) { ClRtlFreeNetAdapterEnum(adapterEnum); } if (eventCode != 0) { wsprintfW(&(errorString[0]), L"%u", status); (*pClNetLogEvent1)(LOG_CRITICAL, eventCode, errorString); } if (status == ERROR_SUCCESS) { ClNetDbgPrint((LOG_NOISE, "[ClNet] Network configuration complete...\n" )); } return(status); } // ClNetConfigureNetworks