356 lines
8 KiB
C
356 lines
8 KiB
C
/*++
|
||
|
||
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()
|