|
|
//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1998.
//
// File: boscomp.cpp
//
// Contents: DllMain
//
// Notes: modified from windows\setup\winnt32\apmupgrd.cpp by wnelson
//
// Author: wnelson 2 Apr 99
//
// ShaoYin 9 Sep 99 revised, add support for Exchange Server
//
//----------------------------------------------------------------------------
#include <winnt32.h>
#include "boscomp.h"
#include "resource.h"
HINSTANCE g_hinst;
// help text files
TCHAR szErrorHTM[] = TEXT("compdata\\boserror.htm"); TCHAR szErrorTXT[] = TEXT("compdata\\boserror.txt");
// help text files (Exchange Server)
TCHAR szExchangeHTM[] = TEXT("compdata\\exchange.htm"); TCHAR szExchangeTXT[] = TEXT("compdata\\exchange.txt");
// bos/sbs 4.5 reg keys, value names, and possible values
const TCHAR szBosKey[] = TEXT("Software\\Microsoft\\Backoffice"); const TCHAR szFamilyIdKey[] = TEXT("FamilyID"); const TCHAR szBosFamilyId[] = TEXT("8D4BCD88-3236-11d2-AB4E-00C04FB1799F"); const TCHAR szSbsFamilyId[] = TEXT("EE2D3727-33C0-11d2-AB50-00C04FB1799F"); const TCHAR szSuiteVersionKey[] = TEXT("SuiteVersion"); const TCHAR szSuiteNameKey[] = TEXT("SuiteName"); const TCHAR sz45Version[] = TEXT("4.5"); const TCHAR szBosName[] = TEXT("BackOffice Server"); const TCHAR szSbsName[] = TEXT("Small Business Server");
// sbs 4.0x reg keys, value names, and values
const TCHAR szSbsKey[] = TEXT("Software\\Microsoft\\Small Business"); const TCHAR szSbsVersionKey[] = TEXT("Version"); const TCHAR szSbs40AVersion[] = TEXT("4.0a"); const TCHAR szProductOptionsKey[] = TEXT("System\\CurrentControlSet\\Control\\ProductOptions"); //const TCHAR szProductOptionsKey[] = TEXT("software\\test");
const TCHAR szProductSuiteKey[] = TEXT("ProductSuite"); const TCHAR szSbsProductSuiteValue[] = TEXT("Small Business"); const TCHAR szSbsRestrictedProductSuiteValue[] = TEXT("Small Business(Restricted)");
// bos 4.0 version
TCHAR szBos40VersionKey[] = TEXT("Version"); TCHAR szBos40Version[] = TEXT("4.0");
// bos 2.5 key
TCHAR szBos25Key[] = TEXT("2.5");
// Exchange 5.5 reg keys, value names.
const TCHAR szExchangeKey[] = TEXT("Software\\Microsoft\\Exchange\\Setup"); const TCHAR szExchangeVerKey[] = TEXT("NewestBuild"); const DWORD dwExchangeVer55 = 0x7a8;
// Exchange 5.5 Server Pack reg key and value name.
const TCHAR szExchangeSvcPackKey[] = TEXT("ServicePackBuild"); const DWORD dwExchangeSvcPack3 = 0xa5a;
//+---------------------------------------------------------------------------
//
// Function: DllMain
//
// Purpose: constructor
//
// Arguments: Standard DLL entry point arguments
//
// Author: wnelson 2 Apr 99
//
// Notes: from kumarp 12 April 97
//
extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReasonForCall, LPVOID lpReserved) { BOOL status = TRUE;
switch( dwReasonForCall ) { case DLL_PROCESS_ATTACH: { g_hinst = hInstance; DisableThreadLibraryCalls(hInstance); } break;
case DLL_PROCESS_DETACH: case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: break; }
return status; }
//+----------------------------------------------------------------------
//
// Function: BosHardBlockCheck
//
// Purpose: This function is called by winnt32.exe so that we
// can check for installed bos/sbs suites that cannot be upgraded to Win2k.
//
//
//
// Arguments:
// CompatibilityCallback [in] pointer to COMPATIBILITYCALLBACK fn
// Context [in] pointer to compatibility context
//
// FALSE if Win2k setup can continue.
// TRUE if Win2k cannot upgrade the installed suite.
//
// Author: wnelson 2 Apr 99
//
// Notes:
// TRUE is returned in the following cases: BOS 2.5; SBS 4.0,4.0a; BOS 4.0
// For SBS, it does not matter if they've upgraded to full NT Server; they still have to
// upgrade their suite to BackOffice 4.5 in order to continue.
//
BOOL WINAPI BosHardBlockCheck(IN PCOMPAIBILITYCALLBACK CompatibilityCallback,IN LPVOID Context) { SuiteVersion eVersion=DetermineInstalledSuite(); if (eVersion==VER_NONE || eVersion==VER_BOS45 || eVersion==VER_POST45) return FALSE; TCHAR szMsg[1024]; GetSuiteMessage(eVersion,szMsg,1024); // Use the callback function to send the signal
COMPATIBILITY_ENTRY ce; ZeroMemory(&ce,sizeof(COMPATIBILITY_ENTRY)); ce.Description = szMsg; ce.HtmlName = szErrorHTM; // defined above
ce.TextName = szErrorTXT; // defined above
ce.RegKeyName = NULL; ce.RegValName = NULL; ce.RegValDataSize = 0; ce.RegValData = NULL; ce.SaveValue = NULL; ce.Flags = 0; CompatibilityCallback(&ce, Context);
return TRUE; } //+----------------------------------------------------------------------
//
// Function: BosSoftBlockCheck
//
// Purpose: This function is called by winnt32.exe so that we
// can check for an installed sbs/bos suite with possible upgrade problems.
//
//
//
// Arguments:
// CompatibilityCallback [in] pointer to COMPATIBILITYCALLBACK fn
// Context [in] pointer to compatibility context
//
// FALSE if Win2k setup can continue.
// TRUE if Win2k setup needs to warn the user that upgrade may impair functionality of installed suite.
//
// Author: wnelson 2 Apr 99
//
// ShaoYin 9 Sep 99, add support for Exchange Server
//
// Notes:
// TRUE is returned in the following cases: BOS 4.5
//
BOOL WINAPI BosSoftBlockCheck(IN PCOMPAIBILITYCALLBACK CompatibilityCallback,IN LPVOID Context) {
BOOL result = FALSE; SuiteVersion eVersion=DetermineInstalledSuite(); if (eVersion==VER_BOS45) { TCHAR szMsg[1024]; GetSuiteMessage(eVersion,szMsg,1024); // Use the callback function to send the signal
COMPATIBILITY_ENTRY ce; ZeroMemory(&ce,sizeof(COMPATIBILITY_ENTRY)); ce.Description = szMsg; ce.HtmlName = szErrorHTM; // defined above
ce.TextName = szErrorTXT; // defined above
ce.RegKeyName = NULL; ce.RegValName = NULL; ce.RegValDataSize = 0; ce.RegValData = NULL; ce.SaveValue = NULL; ce.Flags = 0; CompatibilityCallback(&ce, Context);
result = TRUE; }
ExchangeVersion exVersion = DetermineExchangeVersion(); if (exVersion == EXCHANGE_VER_PRE55SP3) { TCHAR szMsgExchange[1024]; COMPATIBILITY_ENTRY cExchange;
LoadResString(IDS_Exchange, szMsgExchange, 1024); ZeroMemory(&cExchange, sizeof(COMPATIBILITY_ENTRY)); cExchange.Description = szMsgExchange; cExchange.HtmlName = szExchangeHTM; cExchange.TextName = szExchangeTXT; cExchange.RegKeyName = NULL; cExchange.RegValName = NULL; cExchange.RegValData = NULL; cExchange.RegValDataSize = 0; cExchange.SaveValue = NULL; cExchange.Flags = 0; CompatibilityCallback(&cExchange, Context);
result = TRUE; }
return( result ); }
SuiteVersion DetermineInstalledSuite() { SuiteVersion eVersion=VER_NONE; HKEY hKey,hKey25; TCHAR szFamilyId[256], szVersion[256], szSuiteName[256]; DWORD dwVerLen1=256, dwVerLen2=256, dwNameLen=256, dwIdLen=256; DWORD dwDataType=REG_SZ; //
// First look for versions using the bos key (i.e., all bos versions and sbs 4.5 or later)
//
if (ERROR_SUCCESS==RegOpenKey(HKEY_LOCAL_MACHINE,szBosKey,&hKey)) { if(ERROR_SUCCESS==RegQueryValueEx(hKey,szSuiteVersionKey,0,&dwDataType,(LPBYTE)szVersion,&dwVerLen1)) { if(0==_tcsicmp(szVersion,sz45Version)) { // Some 4.5 version is on the box.
if (ERROR_SUCCESS==RegQueryValueEx(hKey,szFamilyIdKey,0,&dwDataType,(LPBYTE)szFamilyId,&dwIdLen)) { if (0==_tcsicmp(szFamilyId,szBosFamilyId) ) { eVersion=VER_BOS45; } else if (0==_tcsicmp(szFamilyId,szSbsFamilyId) ) { eVersion=VER_SBS45; } } else { // The guid just checked is the official version marker; however, 4.5 beta 1 did
// not use the guids. This version is timebombed and should be dead, but just in case
// we'll check the suite name string also.
if (ERROR_SUCCESS==RegQueryValueEx(hKey,szSuiteNameKey,0,&dwDataType, (LPBYTE)szSuiteName,&dwNameLen)) { if (0==_tcsicmp(szSuiteName,szBosName)) { eVersion=VER_BOS45; } else if (0==_tcsicmp(szSuiteName,szSbsName)) { eVersion=VER_SBS45; } } } } else { // A later version is on the box
eVersion=VER_POST45; } } // look for bos 4.0
else if (ERROR_SUCCESS==RegQueryValueEx(hKey,szBos40VersionKey,0,&dwDataType,(LPBYTE)szVersion,&dwVerLen2) && 0==_tcsicmp(szBos40Version,szVersion)) { eVersion=VER_BOS40; } // look for bos 2.5
else if (ERROR_SUCCESS==RegOpenKey(hKey,szBos25Key,&hKey25)) { eVersion=VER_BOS25; RegCloseKey(hKey25); } RegCloseKey(hKey); } //
// Look for SBS versions 4.0a, and 4.0.
//
else if (ProductSuiteContains(szSbsProductSuiteValue)) { //
// If we get here, SBS 4.0 or 4.0a is on the box.
//
if (ERROR_SUCCESS==RegOpenKey(HKEY_LOCAL_MACHINE,szSbsKey,&hKey)) { TCHAR szVersion[256]; DWORD dwVerLen=256; DWORD dwDataType=REG_SZ; if (ERROR_SUCCESS==RegQueryValueEx(hKey,szSbsVersionKey,0,&dwDataType,(LPBYTE)szVersion,&dwVerLen) && 0==_tcsicmp(szVersion,szSbs40AVersion)) { eVersion=VER_SBS40A; } else { eVersion=VER_SBS40; } RegCloseKey(hKey); } } // We have to make sure the user isn't tricking us into allowing Win2k to upgrade
// restricted sbs nt.
if (eVersion==VER_NONE || eVersion==VER_BOS45 || eVersion==VER_POST45) { if (ProductSuiteContains(szSbsRestrictedProductSuiteValue)) { // User tried to fool us by altering version info.
eVersion=VER_SBSREST; } } return eVersion; }
// return the display string for the version in question.
void GetSuiteMessage(SuiteVersion eSV, TCHAR* szMsg, UINT nLen) { szMsg[0]=0; switch (eSV) { case VER_NONE: break; case VER_BOS45: LoadResString(IDS_Bos45Msg,szMsg,nLen); break; case VER_BOS40: LoadResString(IDS_Bos40Msg,szMsg,nLen); break; case VER_BOS25: LoadResString(IDS_Bos25Msg,szMsg,nLen); break; case VER_SBS45: LoadResString(IDS_Sbs45Msg,szMsg,nLen); break; case VER_SBS40: LoadResString(IDS_Sbs40Msg,szMsg,nLen); break; case VER_SBS40A: LoadResString(IDS_Sbs40AMsg,szMsg,nLen); break; case VER_SBSREST: LoadResString(IDS_SbsRestMsg,szMsg,nLen); break; } } void LoadResString(UINT nRes, TCHAR* szString, UINT nLen) { if(!LoadString(g_hinst, nRes, szString, nLen)) { szString[0] = 0; } }
// Check the ProductOptions\ProductSuite multi-sz value for the string szTest.
bool ProductSuiteContains(const TCHAR* szTest) { bool bRet=false; HKEY hKey; unsigned char* Value=NULL; TCHAR* szValue; DWORD dwDataLen=0; DWORD dwDataType=REG_MULTI_SZ;
if (ERROR_SUCCESS == RegOpenKey(HKEY_LOCAL_MACHINE,szProductOptionsKey,&hKey) ) { // see how big the data will be
if (ERROR_SUCCESS == RegQueryValueEx(hKey,szProductSuiteKey,0,&dwDataType,NULL,&dwDataLen)) { Value=new unsigned char[dwDataLen]; if (Value != NULL && dwDataLen != 1) // if the multi-sz is empty, we get back dataLen=1 and don't need to go further
{ if (RegQueryValueEx(hKey,szProductSuiteKey,0,&dwDataType,Value,&dwDataLen) == ERROR_SUCCESS) { szValue=(TCHAR*)Value;
for (UINT n = 1 ; *szValue != 0 ; szValue += _tcslen(szValue) + 1) { if ( _tcsstr(szValue, szTest) != 0) { bRet=true; break; } }
} } if (Value != NULL) delete[] Value; } RegCloseKey(hKey); } return bRet; }
ExchangeVersion DetermineExchangeVersion() { ExchangeVersion eVersion=EXCHANGE_VER_NONE; HKEY hExchangeKey; DWORD dwCurrentVer, dwCurrentSvcPackVer; DWORD dwVerLen=sizeof(DWORD); DWORD dwDataType=REG_DWORD; //
// First look for versions using the Exchange key
//
if (ERROR_SUCCESS==RegOpenKey(HKEY_LOCAL_MACHINE,szExchangeKey,&hExchangeKey)) { if(ERROR_SUCCESS==RegQueryValueEx(hExchangeKey,szExchangeVerKey,0,&dwDataType,(LPBYTE)&dwCurrentVer,&dwVerLen)) { if (dwCurrentVer < dwExchangeVer55) { // prior Exchange 5.5
eVersion=EXCHANGE_VER_PRE55SP3; } else if (dwCurrentVer == dwExchangeVer55) { // Exchange 5.5 version is on the box.
if (ERROR_SUCCESS==RegQueryValueEx(hExchangeKey,szExchangeSvcPackKey,0,&dwDataType,(LPBYTE)&dwCurrentSvcPackVer,&dwVerLen)) { if (dwCurrentSvcPackVer >= dwExchangeSvcPack3) { // has Service Pack 3 installed
eVersion=EXCHANGE_VER_POST55SP3; } else { // no Service Pack 3
eVersion=EXCHANGE_VER_PRE55SP3; } } else { // no Servie Pack 3
eVersion=EXCHANGE_VER_PRE55SP3; } } } RegCloseKey(hExchangeKey); }
return eVersion; }
|