windows-nt/Source/XPSP1/NT/base/cluster/clusapi/intrface.c

356 lines
8 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*++
Copyright (c) 1996-1999 Microsoft Corporation
Module Name:
intrface.c
Abstract:
Provides interface for managing cluster netinterfaces
Author:
John Vert (jvert) 30-Jan-1996
Charlie Wickham (charlwi) 5-Jun-1997
Rod Gamache (rodga) 9-Jun-1997
Revision History:
copied from network.c
--*/
#include "clusapip.h"
HNETINTERFACE
WINAPI
OpenClusterNetInterface(
IN HCLUSTER hCluster,
IN LPCWSTR lpszInterfaceName
)
/*++
Routine Description:
Opens a handle to the specified network interface
Arguments:
hCluster - Supplies a handle to the cluster
lpszInterfaceName - Supplies the name of the netinterface to be opened
Return Value:
non-NULL - returns an open handle to the specified netinterface.
NULL - The operation failed. Extended error status is available
using GetLastError()
--*/
{
PCLUSTER Cluster;
PCNETINTERFACE NetInterface;
error_status_t Status = ERROR_SUCCESS;
//
// get a pointer to the cluster struct, allocate space for the netinterface
// structure and the supplied name.
//
Cluster = (PCLUSTER)hCluster;
NetInterface = LocalAlloc(LMEM_FIXED, sizeof(CNETINTERFACE));
if (NetInterface == NULL) {
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return(NULL);
}
NetInterface->Name = LocalAlloc(LMEM_FIXED, (lstrlenW(lpszInterfaceName)+1)*sizeof(WCHAR));
if (NetInterface->Name == NULL) {
LocalFree(NetInterface);
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return(NULL);
}
//
// init the netinterface struct and call clussvc to open the netinterface
//
lstrcpyW(NetInterface->Name, lpszInterfaceName);
NetInterface->Cluster = Cluster;
InitializeListHead(&NetInterface->NotifyList);
WRAP_NULL(NetInterface->hNetInterface,
(ApiOpenNetInterface(Cluster->RpcBinding,
lpszInterfaceName,
&Status)),
&Status,
Cluster);
if ((NetInterface->hNetInterface == NULL) || (Status != ERROR_SUCCESS)) {
LocalFree(NetInterface->Name);
LocalFree(NetInterface);
SetLastError(Status);
return(NULL);
}
//
// Link newly opened netinterface onto the cluster structure.
//
EnterCriticalSection(&Cluster->Lock);
InsertHeadList(&Cluster->NetInterfaceList, &NetInterface->ListEntry);
LeaveCriticalSection(&Cluster->Lock);
return ((HNETINTERFACE)NetInterface);
}
BOOL
WINAPI
CloseClusterNetInterface(
IN HNETINTERFACE hNetInterface
)
/*++
Routine Description:
Closes a network interface handle returned from OpenClusterNetInterface
Arguments:
hNetInterface - Supplies the netinterface handle
Return Value:
TRUE - The operation was successful.
FALSE - The operation failed. Extended error status is available
using GetLastError()
--*/
{
PCNETINTERFACE NetInterface;
PCLUSTER Cluster;
NetInterface = (PCNETINTERFACE)hNetInterface;
Cluster = (PCLUSTER)NetInterface->Cluster;
//
// Unlink netinterface from cluster list.
//
EnterCriticalSection(&Cluster->Lock);
RemoveEntryList(&NetInterface->ListEntry);
//
// Remove any notifications posted against this netinterface.
//
RundownNotifyEvents(&NetInterface->NotifyList, NetInterface->Name);
//if the cluster is dead and the reconnect has failed,
//the group->hnetinterface might be NULL if s_apiopennetinterface for
//this group failed on a reconnect
//the cluster may be dead and hinterface may be non null, say
//if reconnectnetinterfaces succeeded but say the reconnect networks
//failed
// At reconnect, the old context is saved in the obsolete
// list for deletion when the cluster handle is closed or when
// the next call is made
if ((Cluster->Flags & CLUS_DEAD) && (NetInterface->hNetInterface))
{
RpcSmDestroyClientContext(&NetInterface->hNetInterface);
LeaveCriticalSection(&Cluster->Lock);
goto FnExit;
}
LeaveCriticalSection(&Cluster->Lock);
//
// Close RPC context handle
//
ApiCloseNetInterface(&NetInterface->hNetInterface);
FnExit:
//
// Free memory allocations
//
LocalFree(NetInterface->Name);
LocalFree(NetInterface);
//
// Give the cluster a chance to clean up in case this
// netinterface was the only thing keeping it around.
//
CleanupCluster(Cluster);
return(TRUE);
}
CLUSTER_NETINTERFACE_STATE
WINAPI
GetClusterNetInterfaceState(
IN HNETINTERFACE hNetInterface
)
/*++
Routine Description:
Returns the network interface's current state
Arguments:
hNetInterface - Supplies a handle to a cluster netinterface
Return Value:
Returns the current state of the network interface.
If the function fails, the return value is -1. Extended error
status is available using GetLastError()
--*/
{
PCNETINTERFACE NetInterface;
CLUSTER_NETINTERFACE_STATE State;
DWORD Status;
NetInterface = (PCNETINTERFACE)hNetInterface;
WRAP(Status,
(ApiGetNetInterfaceState( NetInterface->hNetInterface,
(LPDWORD)&State )), // cast for win64 warning
NetInterface->Cluster);
if (Status == ERROR_SUCCESS) {
return(State);
} else {
SetLastError(Status);
return( ClusterNetInterfaceStateUnknown );
}
}
DWORD
WINAPI
GetClusterNetInterface(
IN HCLUSTER hCluster,
IN LPCWSTR lpszNodeName,
IN LPCWSTR lpszNetworkName,
OUT LPWSTR lpszInterfaceName,
IN OUT LPDWORD lpcchInterfaceName
)
/*++
Routine Description:
Gets the name of a node's interface to a network in the cluster.
Arguments:
hCluster - Supplies a handle to the cluster
lpszNodeName - Supplies the node name of the node in the cluster
lpszNetworkName - Supplies the name of the cluster network
lpszInterfaceName - Returns the name of the network interface
lpcchInterfaceName - Points to a variable that specifies the size, in
characters, of the buffer pointed to by the lpszInterfaceName
parameter. This size should include the terminating null
character. When the function returns, the variable pointed to
by lpcchInterfaceName contains the number of characters that
would be stored in the buffer if it were large enough. The count
returned does not include the terminating null character.
Return Value:
If the function succeeds, the return value is ERROR_SUCCESS.
If the function fails, the return value is an error value.
--*/
{
DWORD Status;
DWORD Length;
PCLUSTER Cluster;
LPWSTR Name = NULL;
Cluster = GET_CLUSTER(hCluster);
WRAP(Status,
(ApiGetNetInterface(Cluster->RpcBinding,
lpszNodeName,
lpszNetworkName,
&Name)),
Cluster);
if (Status != ERROR_SUCCESS) {
return(Status);
}
MylstrcpynW(lpszInterfaceName, Name, *lpcchInterfaceName);
Length = lstrlenW(Name);
if (*lpcchInterfaceName < (Length + 1)) {
if (lpszInterfaceName == NULL) {
Status = ERROR_SUCCESS;
} else {
Status = ERROR_MORE_DATA;
}
}
*lpcchInterfaceName = Length;
MIDL_user_free(Name);
return(Status);
}
HCLUSTER
WINAPI
GetClusterFromNetInterface(
IN HNETINTERFACE hNetInterface
)
/*++
Routine Description:
Returns the cluster handle from the associated network interface handle.
Arguments:
hNetInterface - Supplies the network interface.
Return Value:
Handle to the cluster associated with the network interface handle.
--*/
{
DWORD nStatus;
PCNETINTERFACE NetInterface = (PCNETINTERFACE)hNetInterface;
HCLUSTER hCluster = (HCLUSTER)NetInterface->Cluster;
nStatus = AddRefToClusterHandle( hCluster );
if ( nStatus != ERROR_SUCCESS ) {
SetLastError( nStatus );
hCluster = NULL;
}
return( hCluster );
} // GetClusterFromNetInterface()