468 lines
9.2 KiB
C
468 lines
9.2 KiB
C
|
/*++
|
|||
|
|
|||
|
Copyright (c) 1996-2001 Microsoft Corporation
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
oscheck.c
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
Checks all the nooks and crannies of the OS to make sure
|
|||
|
it is ok to run a cluster on it.
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
John Vert (jvert) 11/11/1996
|
|||
|
|
|||
|
Revision History:
|
|||
|
|
|||
|
--*/
|
|||
|
#include <clusrtlp.h>
|
|||
|
|
|||
|
#include <winbase.h>
|
|||
|
|
|||
|
static
|
|||
|
DWORD
|
|||
|
GetEnableClusterRegValue(
|
|||
|
DWORD * pdwValue
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Read the registry override registry value for enabling clusters.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
pdwValue - Return value read from the registry.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
ERROR_SUCCESS if the operation was successful.
|
|||
|
|
|||
|
Win32 error code on failure.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
DWORD sc;
|
|||
|
HKEY hkey = NULL;
|
|||
|
DWORD dwType;
|
|||
|
DWORD cbValue = sizeof( DWORD );
|
|||
|
|
|||
|
if ( !ARGUMENT_PRESENT( pdwValue ) ) {
|
|||
|
return ERROR_INVALID_PARAMETER;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Default to the value 0 - not Enabled!
|
|||
|
//
|
|||
|
*pdwValue = 0;
|
|||
|
|
|||
|
//
|
|||
|
// Open the registry key containing the value.
|
|||
|
//
|
|||
|
|
|||
|
sc = RegOpenKeyEx(
|
|||
|
HKEY_LOCAL_MACHINE,
|
|||
|
TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\Cluster Server"),
|
|||
|
0,
|
|||
|
KEY_READ,
|
|||
|
&hkey );
|
|||
|
if ( sc != ERROR_SUCCESS ) {
|
|||
|
goto Cleanup;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Read the override value.
|
|||
|
//
|
|||
|
|
|||
|
sc = RegQueryValueEx(
|
|||
|
hkey,
|
|||
|
TEXT("EnableCluster"),
|
|||
|
0,
|
|||
|
&dwType,
|
|||
|
(LPBYTE) pdwValue,
|
|||
|
&cbValue );
|
|||
|
if ( sc != ERROR_SUCCESS ) {
|
|||
|
goto Cleanup;
|
|||
|
}
|
|||
|
|
|||
|
Cleanup:
|
|||
|
if ( hkey != NULL ) {
|
|||
|
RegCloseKey( hkey );
|
|||
|
}
|
|||
|
|
|||
|
return( sc );
|
|||
|
|
|||
|
} // GetEnableClusterRegValue
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DWORD
|
|||
|
GetServicePack(
|
|||
|
VOID
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Figures out what service pack is installed
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
The service pack number.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
OSVERSIONINFOW Version;
|
|||
|
LPWSTR p;
|
|||
|
DWORD sp;
|
|||
|
|
|||
|
//
|
|||
|
// Check for required operating system version.
|
|||
|
//
|
|||
|
Version.dwOSVersionInfoSize = sizeof(Version);
|
|||
|
GetVersionExW(&Version);
|
|||
|
if (lstrlenW(Version.szCSDVersion) < lstrlenW(L"Service Pack ")) {
|
|||
|
return(0);
|
|||
|
}
|
|||
|
|
|||
|
p = &Version.szCSDVersion[0] + lstrlenW(L"Service Pack ");
|
|||
|
|
|||
|
sp = wcstoul(p, NULL, 10);
|
|||
|
|
|||
|
return(sp);
|
|||
|
|
|||
|
} // GetServicePack
|
|||
|
|
|||
|
|
|||
|
|
|||
|
BOOL
|
|||
|
ClRtlIsOSValid(
|
|||
|
VOID
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Checks all the nooks and crannies of the OS to see if it is OK to have
|
|||
|
a cluster there.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
TRUE if it's ok.
|
|||
|
|
|||
|
FALSE if it's not ok.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
BOOL fIsValid = FALSE;
|
|||
|
OSVERSIONINFOEX osiv;
|
|||
|
DWORDLONG dwlConditionMask;
|
|||
|
|
|||
|
ZeroMemory( &osiv, sizeof( OSVERSIONINFOEX ) );
|
|||
|
|
|||
|
osiv.dwOSVersionInfoSize = sizeof( OSVERSIONINFOEX );
|
|||
|
|
|||
|
// The following call to VerifyVersionInfo() will test the OS level and that the
|
|||
|
// product suite is Enterprise.
|
|||
|
|
|||
|
osiv.dwMajorVersion = 5;
|
|||
|
osiv.dwMinorVersion = 1;
|
|||
|
osiv.wServicePackMajor = 0;
|
|||
|
osiv.wSuiteMask = VER_SUITE_ENTERPRISE;
|
|||
|
|
|||
|
dwlConditionMask = (DWORDLONG) 0L;
|
|||
|
|
|||
|
VER_SET_CONDITION( dwlConditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL );
|
|||
|
VER_SET_CONDITION( dwlConditionMask, VER_MINORVERSION, VER_GREATER_EQUAL );
|
|||
|
VER_SET_CONDITION( dwlConditionMask, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL );
|
|||
|
VER_SET_CONDITION( dwlConditionMask, VER_SUITENAME, VER_AND );
|
|||
|
|
|||
|
if ( VerifyVersionInfo( &osiv,
|
|||
|
VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR |
|
|||
|
VER_SUITENAME,
|
|||
|
dwlConditionMask ) ) {
|
|||
|
fIsValid = TRUE;
|
|||
|
goto Cleanup;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Check if embedded
|
|||
|
//
|
|||
|
osiv.wSuiteMask = VER_SUITE_EMBEDDEDNT;
|
|||
|
if ( VerifyVersionInfo( &osiv,
|
|||
|
VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR |
|
|||
|
VER_SUITENAME,
|
|||
|
dwlConditionMask ) ) {
|
|||
|
fIsValid = TRUE;
|
|||
|
goto Cleanup;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Is the default node limit greater than 0?
|
|||
|
//
|
|||
|
if ( ClRtlGetDefaultNodeLimit( ClRtlGetSuiteType() ) > 0 ) {
|
|||
|
fIsValid = TRUE;
|
|||
|
goto Cleanup;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// If we get here, the this version of the OS won't support clustering.
|
|||
|
//
|
|||
|
SetLastError( ERROR_CLUSTER_WRONG_OS_VERSION );
|
|||
|
|
|||
|
Cleanup:
|
|||
|
return( fIsValid );
|
|||
|
|
|||
|
} // ClRtlIsOSValid
|
|||
|
|
|||
|
|
|||
|
BOOL
|
|||
|
ClRtlIsOSTypeValid(
|
|||
|
VOID
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Checks to see if the operating system type (server, Enterprise, whatever) is
|
|||
|
ok to install a cluster.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
TRUE if it's ok.
|
|||
|
|
|||
|
FALSE if it's not ok.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
BOOL fIsValid = FALSE;
|
|||
|
OSVERSIONINFOEX osiv;
|
|||
|
DWORDLONG dwlConditionMask;
|
|||
|
|
|||
|
ZeroMemory( &osiv, sizeof( OSVERSIONINFOEX ) );
|
|||
|
|
|||
|
osiv.dwOSVersionInfoSize = sizeof( OSVERSIONINFOEX );
|
|||
|
|
|||
|
// The call to VerifyVersionInfo will test whether product suite is Advanced
|
|||
|
// Server, aka "Enterprise".
|
|||
|
|
|||
|
osiv.wSuiteMask = VER_SUITE_ENTERPRISE;
|
|||
|
|
|||
|
dwlConditionMask = (DWORDLONG) 0L;
|
|||
|
|
|||
|
VER_SET_CONDITION( dwlConditionMask, VER_SUITENAME, VER_AND );
|
|||
|
|
|||
|
// Is this Datacenter or Advanced Server?
|
|||
|
|
|||
|
if ( VerifyVersionInfo( &osiv, VER_SUITENAME, dwlConditionMask ) ) {
|
|||
|
fIsValid = TRUE;
|
|||
|
goto Cleanup;
|
|||
|
}
|
|||
|
|
|||
|
// Is this Embedded NT?
|
|||
|
|
|||
|
osiv.wSuiteMask = VER_SUITE_EMBEDDEDNT;
|
|||
|
if ( VerifyVersionInfo( &osiv, VER_SUITENAME, dwlConditionMask ) ) {
|
|||
|
fIsValid = TRUE;
|
|||
|
goto Cleanup;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Is the default node limit greater than 0?
|
|||
|
//
|
|||
|
if ( ClRtlGetDefaultNodeLimit( ClRtlGetSuiteType() ) > 0 ) {
|
|||
|
fIsValid = TRUE;
|
|||
|
goto Cleanup;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// If we get here, the this version of the OS won't support clustering.
|
|||
|
//
|
|||
|
SetLastError( ERROR_CLUSTER_WRONG_OS_VERSION );
|
|||
|
|
|||
|
Cleanup:
|
|||
|
return( fIsValid );
|
|||
|
|
|||
|
} // ClRtlIsOSTypeValid
|
|||
|
|
|||
|
//*********************************************************
|
|||
|
|
|||
|
#define DATACENTER_DEFAULT_NODE_LIMIT 8
|
|||
|
#define ADVANCEDSERVER_DEFAULT_NODE_LIMIT 4
|
|||
|
#define EMBEDDED_DEFAULT_NODE_LIMIT 4
|
|||
|
#define SERVER_DEFAULT_NODE_LIMIT 0 // ** not used currently **
|
|||
|
|
|||
|
//*********************************************************
|
|||
|
|
|||
|
DWORD
|
|||
|
ClRtlGetDefaultNodeLimit(
|
|||
|
DWORD SuiteType
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Determines the default maximum number of nodes allowed in the cluster, based
|
|||
|
on the product suite.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
The default maximum number of nodes allowed in the cluster.
|
|||
|
|
|||
|
Note that this function will return ZERO if the product suite is neither
|
|||
|
DataCenter, Advanced Server (aka Enterprise), nor Embedded.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
DWORD NodeLimit;
|
|||
|
|
|||
|
switch( SuiteType )
|
|||
|
{
|
|||
|
case DataCenter:
|
|||
|
NodeLimit = DATACENTER_DEFAULT_NODE_LIMIT;
|
|||
|
break;
|
|||
|
|
|||
|
case Enterprise:
|
|||
|
NodeLimit = ADVANCEDSERVER_DEFAULT_NODE_LIMIT;
|
|||
|
break;
|
|||
|
|
|||
|
case EmbeddedNT:
|
|||
|
NodeLimit = EMBEDDED_DEFAULT_NODE_LIMIT;
|
|||
|
break;
|
|||
|
|
|||
|
case VER_SERVER_NT:
|
|||
|
default:
|
|||
|
{
|
|||
|
DWORD dwOverride;
|
|||
|
|
|||
|
//
|
|||
|
// Check the override registry value.
|
|||
|
//
|
|||
|
GetEnableClusterRegValue( &dwOverride );
|
|||
|
if ( dwOverride != 0 ) {
|
|||
|
NodeLimit = 2;
|
|||
|
} else {
|
|||
|
NodeLimit = 0;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
return( NodeLimit );
|
|||
|
|
|||
|
} // ClRtlGetDefaultNodeLimit
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DWORD
|
|||
|
ClRtlGetSuiteType(
|
|||
|
void
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Returns the current product suite type.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Returns the product suite type DataCenter or Enterprise (aka Advanced Server)
|
|||
|
Returns zero if not DataCenter or Enterprise
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
DWORD dwSuiteType = 0;
|
|||
|
OSVERSIONINFOEX osiv;
|
|||
|
DWORDLONG dwlConditionMask;
|
|||
|
|
|||
|
ZeroMemory( &osiv, sizeof( OSVERSIONINFOEX ) );
|
|||
|
osiv.dwOSVersionInfoSize = sizeof( OSVERSIONINFOEX );
|
|||
|
|
|||
|
// First check if product suite is DataCenter.
|
|||
|
|
|||
|
osiv.wSuiteMask = VER_SUITE_DATACENTER;
|
|||
|
dwlConditionMask = (DWORDLONG) 0L;
|
|||
|
|
|||
|
VER_SET_CONDITION( dwlConditionMask, VER_SUITENAME, VER_AND );
|
|||
|
|
|||
|
if ( VerifyVersionInfo( &osiv, VER_SUITENAME, dwlConditionMask ) == TRUE )
|
|||
|
{
|
|||
|
// This is DataCenter.
|
|||
|
|
|||
|
dwSuiteType = DataCenter;
|
|||
|
goto Cleanup;
|
|||
|
}
|
|||
|
|
|||
|
ZeroMemory( &osiv, sizeof( OSVERSIONINFOEX ) );
|
|||
|
osiv.dwOSVersionInfoSize = sizeof( OSVERSIONINFOEX );
|
|||
|
|
|||
|
// Next check if this is Advanced Server (Enterprise).
|
|||
|
|
|||
|
osiv.wSuiteMask = VER_SUITE_ENTERPRISE;
|
|||
|
dwlConditionMask = (DWORDLONG) 0L;
|
|||
|
|
|||
|
VER_SET_CONDITION( dwlConditionMask, VER_SUITENAME, VER_AND );
|
|||
|
|
|||
|
if ( VerifyVersionInfo( &osiv, VER_SUITENAME, dwlConditionMask ) == TRUE )
|
|||
|
{
|
|||
|
dwSuiteType = Enterprise;
|
|||
|
goto Cleanup;
|
|||
|
}
|
|||
|
|
|||
|
// Next check if this is Embedded.
|
|||
|
|
|||
|
osiv.wSuiteMask = VER_SUITE_EMBEDDEDNT;
|
|||
|
dwlConditionMask = (DWORDLONG) 0L;
|
|||
|
|
|||
|
VER_SET_CONDITION( dwlConditionMask, VER_SUITENAME, VER_AND );
|
|||
|
|
|||
|
if ( VerifyVersionInfo( &osiv, VER_SUITENAME, dwlConditionMask ) == TRUE )
|
|||
|
{
|
|||
|
dwSuiteType = EmbeddedNT;
|
|||
|
goto Cleanup;
|
|||
|
}
|
|||
|
|
|||
|
// Finally check if this is any Server.
|
|||
|
|
|||
|
if ( GetVersionEx( (LPOSVERSIONINFO) &osiv ) ) {
|
|||
|
if ( osiv.wProductType == VER_NT_SERVER ) {
|
|||
|
dwSuiteType = VER_SERVER_NT;
|
|||
|
goto Cleanup;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
Cleanup:
|
|||
|
return( dwSuiteType );
|
|||
|
|
|||
|
} // ClRtlGetSuiteType
|