mirror of https://github.com/tongzx/nt5src
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
355 lines
8.0 KiB
355 lines
8.0 KiB
/*++
|
|
|
|
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()
|