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

595 lines
12 KiB
C
Raw Permalink Normal View History

2020-09-26 03:20:57 -05:00
/*++
Copyright (c) 1996-1999 Microsoft Corporation
Module Name:
network.c
Abstract:
Provides interface for managing cluster networks
Author:
John Vert (jvert) 30-Jan-1996
Charlie Wickham (charlwi) 5-Jun-1997
Revision History:
copied from group.c
--*/
#include "clusapip.h"
HNETWORK
WINAPI
OpenClusterNetwork(
IN HCLUSTER hCluster,
IN LPCWSTR lpszNetworkName
)
/*++
Routine Description:
Opens a handle to the specified network
Arguments:
hCluster - Supplies a handle to the cluster
lpszNetworkName - Supplies the name of the network to be opened
Return Value:
non-NULL - returns an open handle to the specified network.
NULL - The operation failed. Extended error status is available
using GetLastError()
--*/
{
PCLUSTER Cluster;
PCNETWORK Network;
error_status_t Status = ERROR_SUCCESS;
//
// get a pointer to the cluster struct, alloocate space for the network
// structure and the supplied name.
//
Cluster = (PCLUSTER)hCluster;
Network = LocalAlloc(LMEM_FIXED, sizeof(CNETWORK));
if (Network == NULL) {
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return(NULL);
}
Network->Name = LocalAlloc(LMEM_FIXED, (lstrlenW(lpszNetworkName)+1)*sizeof(WCHAR));
if (Network->Name == NULL) {
LocalFree(Network);
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return(NULL);
}
//
// init the network struct and call clussvc to open the network
//
lstrcpyW(Network->Name, lpszNetworkName);
Network->Cluster = Cluster;
InitializeListHead(&Network->NotifyList);
WRAP_NULL(Network->hNetwork,
(ApiOpenNetwork(Cluster->RpcBinding,
lpszNetworkName,
&Status)),
&Status,
Cluster);
if ((Network->hNetwork == NULL) || (Status != ERROR_SUCCESS)) {
LocalFree(Network->Name);
LocalFree(Network);
SetLastError(Status);
return(NULL);
}
//
// Link newly opened network onto the cluster structure.
//
EnterCriticalSection(&Cluster->Lock);
InsertHeadList(&Cluster->NetworkList, &Network->ListEntry);
LeaveCriticalSection(&Cluster->Lock);
return ((HNETWORK)Network);
}
BOOL
WINAPI
CloseClusterNetwork(
IN HNETWORK hNetwork
)
/*++
Routine Description:
Closes a network handle returned from OpenClusterNetwork
Arguments:
hNetwork - Supplies the network handle
Return Value:
TRUE - The operation was successful.
FALSE - The operation failed. Extended error status is available
using GetLastError()
--*/
{
PCNETWORK Network;
PCLUSTER Cluster;
Network = (PCNETWORK)hNetwork;
Cluster = (PCLUSTER)Network->Cluster;
//
// Unlink network from cluster list.
//
EnterCriticalSection(&Cluster->Lock);
RemoveEntryList(&Network->ListEntry);
//
// Remove any notifications posted against this network.
//
RundownNotifyEvents(&Network->NotifyList, Network->Name);
//if the cluster is dead and the reconnect has failed,
//the Network->hNetwork might be NULL if s_apiopennetinterface for
//this network failed on a reconnect
//the cluster may be dead and hinterface may be non null, say
//if reconnectnetworks succeeded but say the reconnectgroups
//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) && (Network->hNetwork))
{
RpcSmDestroyClientContext(&Network->hNetwork);
LeaveCriticalSection(&Cluster->Lock);
goto FnExit;
}
LeaveCriticalSection(&Cluster->Lock);
//
// Close RPC context handle
//
ApiCloseNetwork(&Network->hNetwork);
FnExit:
//
// Free memory allocations
//
LocalFree(Network->Name);
LocalFree(Network);
//
// Give the cluster a chance to clean up in case this
// network was the only thing keeping it around.
//
CleanupCluster(Cluster);
return(TRUE);
}
CLUSTER_NETWORK_STATE
WINAPI
GetClusterNetworkState(
IN HNETWORK hNetwork
)
/*++
Routine Description:
Returns the network's current state
Arguments:
hNetwork - Supplies a handle to a cluster network
Return Value:
Returns the current state of the network.
If the function fails, the return value is -1. Extended error
status is available using GetLastError()
--*/
{
PCNETWORK Network;
CLUSTER_NETWORK_STATE State;
DWORD Status;
Network = (PCNETWORK)hNetwork;
WRAP(Status,
(ApiGetNetworkState( Network->hNetwork,
(LPDWORD)&State )), // cast for win64 warning
Network->Cluster);
if (Status == ERROR_SUCCESS) {
return(State);
} else {
SetLastError(Status);
return( ClusterNetworkStateUnknown );
}
}
DWORD
WINAPI
SetClusterNetworkName(
IN HNETWORK hNetwork,
IN LPCWSTR lpszNetworkName
)
/*++
Routine Description:
Sets the friendly name of a cluster network
Arguments:
hNetwork - Supplies a handle to a cluster network
lpszNetworkName - Supplies the new name of the cluster network
cchName - ?
Return Value:
ERROR_SUCCESS if successful
Win32 error code otherwise
--*/
{
PCNETWORK Network;
DWORD Status;
Network = (PCNETWORK)hNetwork;
WRAP(Status,
(ApiSetNetworkName(Network->hNetwork, lpszNetworkName)),
Network->Cluster);
return(Status);
}
DWORD
WINAPI
GetClusterNetworkId(
IN HNETWORK hNetwork,
OUT LPWSTR lpszNetworkId,
IN OUT LPDWORD lpcchName
)
/*++
Routine Description:
Returns the unique identifier of the specified network
Arguments:
hNetwork - Supplies the network whose unique ID is to be returned.
lpszNetworkId - Points to a buffer that receives the unique ID of the object,
including the terminating null character.
lpcchName - Points to a variable that specifies the size, in characters
of the buffer pointed to by the lpszNetworkId parameter. This size
should include the terminating null character. When the function
returns, the variable pointed to be lpcchName contains the number
of characters stored in the buffer. 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;
PCNETWORK Network = (PCNETWORK)hNetwork;
LPWSTR Guid=NULL;
WRAP(Status,
(ApiGetNetworkId(Network->hNetwork,
&Guid)),
Network->Cluster);
if (Status != ERROR_SUCCESS) {
return(Status);
}
MylstrcpynW(lpszNetworkId, Guid, *lpcchName);
Length = lstrlenW(Guid);
if (Length >= *lpcchName) {
if (lpszNetworkId == NULL) {
Status = ERROR_SUCCESS;
} else {
Status = ERROR_MORE_DATA;
}
}
*lpcchName = Length;
MIDL_user_free(Guid);
return(Status);
}
HNETWORKENUM
WINAPI
ClusterNetworkOpenEnum(
IN HNETWORK hNetwork,
IN DWORD dwType
)
/*++
Routine Description:
Initiates an enumeration of the existing cluster network objects.
Arguments:
hNetwork - Supplies a handle to the specific network.
dwType - Supplies a bitmask of the type of properties to be
enumerated.
Return Value:
If successful, returns a handle suitable for use with ClusterNetworkEnum
If unsuccessful, returns NULL and GetLastError() returns a more
specific error code.
--*/
{
PCNETWORK Network = (PCNETWORK)hNetwork;
PENUM_LIST Enum = NULL;
DWORD errorStatus;
//
// validate bitmask
//
if ((dwType & CLUSTER_NETWORK_ENUM_ALL) == 0) {
SetLastError(ERROR_INVALID_PARAMETER);
return(NULL);
}
if ((dwType & ~CLUSTER_NETWORK_ENUM_ALL) != 0) {
SetLastError(ERROR_INVALID_PARAMETER);
return(NULL);
}
//
// open connection to service for enum'ing
//
WRAP(errorStatus,
(ApiCreateNetworkEnum(Network->hNetwork,
dwType,
&Enum)),
Network->Cluster);
if (errorStatus != ERROR_SUCCESS) {
SetLastError(errorStatus);
return(NULL);
}
return((HNETWORKENUM)Enum);
}
DWORD
WINAPI
ClusterNetworkGetEnumCount(
IN HNETWORKENUM hNetworkEnum
)
/*++
Routine Description:
Gets the number of items contained the the enumerator's collection.
Arguments:
hEnum - a handle to an enumerator returned by ClusterNetworkOpenEnum.
Return Value:
The number of items (possibly zero) in the enumerator's collection.
--*/
{
PENUM_LIST Enum = (PENUM_LIST)hNetworkEnum;
return Enum->EntryCount;
}
DWORD
WINAPI
ClusterNetworkEnum(
IN HNETWORKENUM hNetworkEnum,
IN DWORD dwIndex,
OUT LPDWORD lpdwType,
OUT LPWSTR lpszName,
IN OUT LPDWORD lpcchName
)
/*++
Routine Description:
Returns the next enumerable resource object.
Arguments:
hNetworkEnum - Supplies a handle to an open cluster network enumeration
returned by ClusterNetworkOpenEnum
dwIndex - Supplies the index to enumerate. This parameter should be
zero for the first call to the ClusterEnum function and then
incremented for subsequent calls.
lpdwType - Returns the type of network.
lpszName - Points to a buffer that receives the name of the network
object, including the terminating null character.
lpcchName - Points to a variable that specifies the size, in characters,
of the buffer pointed to by the lpszName parameter. This size
should include the terminating null character. When the function
returns, the variable pointed to by lpcchName contains the
number of characters stored in the buffer. 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 NameLen;
PENUM_LIST Enum = (PENUM_LIST)hNetworkEnum;
if (dwIndex >= Enum->EntryCount) {
return(ERROR_NO_MORE_ITEMS);
}
NameLen = lstrlenW( Enum->Entry[dwIndex].Name );
MylstrcpynW(lpszName, Enum->Entry[dwIndex].Name, *lpcchName);
if (*lpcchName < (NameLen + 1)) {
if (lpszName == NULL) {
Status = ERROR_SUCCESS;
} else {
Status = ERROR_MORE_DATA;
}
} else {
Status = ERROR_SUCCESS;
}
*lpdwType = Enum->Entry[dwIndex].Type;
*lpcchName = NameLen;
return(Status);
}
DWORD
WINAPI
ClusterNetworkCloseEnum(
IN HNETWORKENUM hNetworkEnum
)
/*++
Routine Description:
Closes an open enumeration for a network.
Arguments:
hNetworkEnum - Supplies a handle to the enumeration to be closed.
Return Value:
If the function succeeds, the return value is ERROR_SUCCESS.
If the function fails, the return value is an error value.
--*/
{
DWORD i;
PENUM_LIST Enum = (PENUM_LIST)hNetworkEnum;
//
// Walk through enumeration freeing all the names
//
for (i=0; i<Enum->EntryCount; i++) {
MIDL_user_free(Enum->Entry[i].Name);
}
MIDL_user_free(Enum);
return(ERROR_SUCCESS);
}
HCLUSTER
WINAPI
GetClusterFromNetwork(
IN HNETWORK hNetwork
)
/*++
Routine Description:
Returns the cluster handle from the associated network handle.
Arguments:
hNetwork - Supplies the network.
Return Value:
Handle to the cluster associated with the network handle.
--*/
{
DWORD nStatus;
PCNETWORK Network = (PCNETWORK)hNetwork;
HCLUSTER hCluster = (HCLUSTER)Network->Cluster;
nStatus = AddRefToClusterHandle( hCluster );
if ( nStatus != ERROR_SUCCESS ) {
SetLastError( nStatus );
hCluster = NULL;
}
return( hCluster );
} // GetClusterFromNetwork()