2373 lines
63 KiB
C
2373 lines
63 KiB
C
/*++
|
||
|
||
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 <nt.h>
|
||
#include <ntrtl.h>
|
||
#include <nturtl.h>
|
||
#include <windows.h>
|
||
#include <cluster.h>
|
||
#include <clusrpc.h>
|
||
#include <clnetcfg.h>
|
||
#include <wchar.h>
|
||
|
||
|
||
//
|
||
// 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; i<NetworkEnum->NetworkCount; 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; i<InterfaceEnum1->InterfaceCount; 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; i<InterfaceEnum->InterfaceCount; 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; i<NodeEnum1->NodeCount; 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; i<NodeEnum->NodeCount; 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 "<network name> - <node name>".
|
||
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
|
||
|
||
|