332 lines
9.2 KiB
C
332 lines
9.2 KiB
C
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Copyright (c) 1996-1998 Microsoft Corporation
|
|
//
|
|
// Module Name:
|
|
// incompat.cpp
|
|
//
|
|
// Abstract:
|
|
// This file implements compatibility checking for various components.
|
|
// The functions get executed by winnt32. It's purpose is to alert the user to possible
|
|
// incompatibilities that may be encountered after performing an upgrade.
|
|
//
|
|
//
|
|
// Author:
|
|
// matt thomlinson (mattt)
|
|
//
|
|
// Notes:
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "precomp.h"
|
|
#pragma hdrstop
|
|
|
|
HRESULT CertSrv_TestForIllegalUpgrade(BOOL *pfComplain);
|
|
extern HINSTANCE hInst;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CertificateServerUpgradeCompatibilityCheck
|
|
//
|
|
// Routine Description:
|
|
// This is the exported function, called to check for incompatibilities when
|
|
// upgrading the machine.
|
|
//
|
|
// Behavior: If Certificate server is installed on NT4, we wish to warn the user.
|
|
//
|
|
// Arguments:
|
|
// pfnCompatibilityCallback - points to the callback function used to supply
|
|
// compatibility information to winnt32.exe.
|
|
// pvContext - points to a context buffer supplied by winnt32.exe.
|
|
//
|
|
//
|
|
// Return Value:
|
|
// TRUE - either indicates that no incompatibility was detected or that
|
|
// *pfnComaptibilityCallback() returned TRUE.
|
|
// FALSE - *pfnCompatibilityCallback() returned FALSE
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
BOOL CertificateServerUpgradeCompatibilityCheck( PCOMPAIBILITYCALLBACK pfnCompatibilityCallback,
|
|
LPVOID pvContext )
|
|
{
|
|
BOOL fReturnValue = (BOOL) TRUE;
|
|
BOOL fComplain;
|
|
|
|
// Is this an illegal upgrade?
|
|
if ((S_OK == CertSrv_TestForIllegalUpgrade(&fComplain)) &&
|
|
fComplain)
|
|
{
|
|
// It is necessary to display a compatibility warning.
|
|
|
|
TCHAR tszDescription[MAX_PATH]; // size is arbitrary
|
|
TCHAR tszHtmlName[MAX_PATH];
|
|
TCHAR tszTextName[MAX_PATH];
|
|
|
|
COMPATIBILITY_ENTRY CompatibilityEntry;
|
|
ZeroMemory( &CompatibilityEntry, sizeof( CompatibilityEntry ) );
|
|
|
|
// Set the Description string.
|
|
|
|
*tszDescription = TEXT( '\0' );
|
|
|
|
LoadString( hInst,
|
|
IDS_CERTSRV_UPGRADE_WARNING,
|
|
tszDescription,
|
|
sizeof(tszDescription)/sizeof(tszDescription[0]) );
|
|
|
|
// Set the HTML file name.
|
|
_tcscpy( tszHtmlName, TEXT( "CompData\\certsrv.htm" ) );
|
|
|
|
// Set the TEXT file name.
|
|
_tcscpy( tszTextName, TEXT( "CompData\\certsrv.txt" ) );
|
|
|
|
// Build the COMPATIBILITY_ENTRY structure to pass to *pfnCompatibilityCallback().
|
|
CompatibilityEntry.Description = tszDescription;
|
|
CompatibilityEntry.HtmlName = tszHtmlName;
|
|
CompatibilityEntry.TextName = tszTextName;
|
|
|
|
// Execute the callback function.
|
|
fReturnValue = pfnCompatibilityCallback( (PCOMPATIBILITY_ENTRY) &CompatibilityEntry,
|
|
pvContext );
|
|
}
|
|
else
|
|
{
|
|
// It is not necessary to display a compatibility warning.
|
|
|
|
fReturnValue = (BOOL) TRUE;
|
|
} // Is it necessary to display a compatibility warning?
|
|
|
|
return ( fReturnValue );
|
|
}
|
|
|
|
|
|
|
|
HRESULT CertSrv_TestForIllegalUpgrade(BOOL *pfComplain)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
SC_HANDLE hSC=NULL, hSvc=NULL;
|
|
OSVERSIONINFO osVer;
|
|
|
|
// only complain about NT4 certsvr upgrades
|
|
|
|
*pfComplain = FALSE;
|
|
osVer.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
|
|
|
if(! GetVersionEx(&osVer) )
|
|
{
|
|
// error getting version, can't be NT4
|
|
hr = GetLastError();
|
|
goto error;
|
|
}
|
|
|
|
if ((osVer.dwPlatformId != VER_PLATFORM_WIN32_NT) ||
|
|
(osVer.dwMajorVersion != 4))
|
|
{
|
|
goto NoComplaint;
|
|
// not NT4, must be ok
|
|
}
|
|
|
|
// now the hard part -- open the service to see if it exists
|
|
hSC = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT);
|
|
if (hSC == NULL)
|
|
{
|
|
hr = GetLastError();
|
|
goto error;
|
|
}
|
|
|
|
hSvc = OpenService(hSC, TEXT("CertSvc"), SERVICE_QUERY_CONFIG);
|
|
if (hSvc == NULL)
|
|
{
|
|
hr = GetLastError();
|
|
if (ERROR_SERVICE_DOES_NOT_EXIST == hr)
|
|
goto NoComplaint;
|
|
goto error;
|
|
}
|
|
|
|
// failed version check and service is installed
|
|
*pfComplain = TRUE;
|
|
|
|
NoComplaint:
|
|
hr = S_OK;
|
|
|
|
error:
|
|
|
|
if (NULL != hSC)
|
|
CloseServiceHandle(hSC);
|
|
|
|
if (NULL != hSvc)
|
|
CloseServiceHandle(hSvc);
|
|
|
|
return hr;
|
|
}
|
|
|
|
BOOL
|
|
IsStandardServerSKU(
|
|
PBOOL pIsServer
|
|
)
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// IsStandardServerSKU
|
|
//
|
|
// Routine Description:
|
|
// This routine determines if the user is running the standard server
|
|
// SKU
|
|
//
|
|
//
|
|
// Arguments:
|
|
// pIsServer - indicates if the server is the standard server SKU
|
|
// or not.
|
|
//
|
|
// Return Value:
|
|
// Indicates success of the check
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
{
|
|
BOOL fReturnValue = (BOOL) FALSE;
|
|
OSVERSIONINFOEX VersionInfo;
|
|
BOOL IsServer = FALSE;
|
|
|
|
//
|
|
// get the current SKU.
|
|
//
|
|
VersionInfo.dwOSVersionInfoSize = sizeof(VersionInfo);
|
|
if (GetVersionEx((OSVERSIONINFO *)&VersionInfo)) {
|
|
fReturnValue = TRUE;
|
|
//
|
|
// is it some sort of server SKU?
|
|
//
|
|
if (VersionInfo.wProductType != VER_NT_WORKSTATION) {
|
|
|
|
//
|
|
// standard server or a server variant?
|
|
//
|
|
if ((VersionInfo.wSuiteMask & (VER_SUITE_ENTERPRISE | VER_SUITE_DATACENTER)) == 0) {
|
|
//
|
|
// it's standard server
|
|
//
|
|
IsServer = TRUE;
|
|
}
|
|
|
|
}
|
|
|
|
*pIsServer = IsServer;
|
|
|
|
}
|
|
|
|
return(fReturnValue);
|
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// ProcessorUpgradeCompatibilityCheck
|
|
//
|
|
// Routine Description:
|
|
// This is the exported function, called to check for incompatibilities when
|
|
// upgrading the machine.
|
|
//
|
|
// Behavior: If the current processor count is > that allowed after upgrade,
|
|
// a warning is generated.
|
|
//
|
|
// Arguments:
|
|
// pfnCompatibilityCallback - points to the callback function used to supply
|
|
// compatibility information to winnt32.exe.
|
|
// pvContext - points to a context buffer supplied by winnt32.exe.
|
|
//
|
|
//
|
|
// Return Value:
|
|
// TRUE - either indicates that no incompatibility was detected or that
|
|
// *pfnComaptibilityCallback() returned TRUE.
|
|
// FALSE - *pfnCompatibilityCallback() returned FALSE
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
BOOL ProcessorUpgradeCompatibilityCheck( PCOMPAIBILITYCALLBACK pfnCompatibilityCallback,
|
|
LPVOID pvContext )
|
|
{
|
|
BOOL fReturnValue = (BOOL) TRUE;
|
|
BOOL fComplain = FALSE;
|
|
BOOL IsServer = FALSE;
|
|
SYSTEM_INFO SysInfo;
|
|
ULONG SourceSkuId;
|
|
ULONG DontCare;
|
|
|
|
|
|
//
|
|
// we only care about standard server SKU.
|
|
//
|
|
SourceSkuId = DetermineSourceProduct(&DontCare,NULL);
|
|
|
|
if ( SourceSkuId == COMPLIANCE_SKU_NTSFULL || SourceSkuId == COMPLIANCE_SKU_NTSU) {
|
|
//
|
|
// we only allow 2 processors on standard server.
|
|
//
|
|
DWORD AllowedCount = 2;
|
|
|
|
GetSystemInfo(&SysInfo);
|
|
if (SysInfo.dwNumberOfProcessors > AllowedCount) {
|
|
fComplain = TRUE;
|
|
}
|
|
}
|
|
|
|
// Is this an illegal upgrade?
|
|
if (fComplain)
|
|
{
|
|
// It is necessary to display a compatibility warning.
|
|
|
|
TCHAR tszDescription[MAX_PATH]; // size is arbitrary
|
|
TCHAR tszHtmlName[MAX_PATH];
|
|
TCHAR tszTextName[MAX_PATH];
|
|
|
|
COMPATIBILITY_ENTRY CompatibilityEntry;
|
|
ZeroMemory( &CompatibilityEntry, sizeof( CompatibilityEntry ) );
|
|
|
|
// Set the Description string.
|
|
|
|
*tszDescription = TEXT( '\0' );
|
|
|
|
LoadString( hInst,
|
|
IDS_PROCESSOR_UPGRADE_WARNING,
|
|
tszDescription,
|
|
sizeof(tszDescription)/sizeof(tszDescription[0]) );
|
|
|
|
// Set the HTML file name.
|
|
_tcscpy( tszHtmlName, TEXT( "CompData\\proccnt.htm" ) );
|
|
|
|
// Set the TEXT file name.
|
|
_tcscpy( tszTextName, TEXT( "CompData\\proccnt.txt" ) );
|
|
|
|
// Build the COMPATIBILITY_ENTRY structure to pass to *pfnCompatibilityCallback().
|
|
CompatibilityEntry.Description = tszDescription;
|
|
CompatibilityEntry.HtmlName = tszHtmlName;
|
|
CompatibilityEntry.TextName = tszTextName;
|
|
|
|
// Execute the callback function.
|
|
fReturnValue = pfnCompatibilityCallback( (PCOMPATIBILITY_ENTRY) &CompatibilityEntry,
|
|
pvContext );
|
|
}
|
|
else
|
|
{
|
|
// It is not necessary to display a compatibility warning.
|
|
|
|
fReturnValue = (BOOL) TRUE;
|
|
} // Is it necessary to display a compatibility warning?
|
|
|
|
return ( fReturnValue );
|
|
}
|