/*++ 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()