///////////////////////////////////////////////////////////////////////////// // // Copyright(C) 2000 Microsoft Corporation all rights reserved. // // Module: setup.cpp // // Project: Windows 2000 IAS // // Description: IAS Upgrade class implementation // // Author: tperraut 06/13/2000 // // Revision // ///////////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "doupgrade.h" #include "iasdb.h" #include "setup.h" // to get the CIASUpgrade class //////////////////////////// // CIASUpgrade Constructor //////////////////////////// CIASUpgrade::CIASUpgrade() { /////////////////////////////////////////////////////////////// // Expand the three string even if two only might be needed in // the netshell scenario // The mdb files can be: // \ias\iasnew.mdb"; // \ias\ias.mdb"; // \ias\iasold.mdb"; /////////////////////////////////////////////////////////////// wchar_t sysWow64Path[MAX_PATH+1] = L""; // // << GetSystemWow64Directory>> returns the number of chars copied to the buffer. // If we get zero back, then we need to check the last error code to see what the // reason for failure was. If it was call not implemented then we know we are // running on native x86. // UINT uReturn = GetSystemWow64DirectoryW(sysWow64Path, MAX_PATH); if ( uReturn != 0 ) { // proper path found m_pIASNewMdb = sysWow64Path; m_pIASNewMdb += L"\\ias\\iasnew.mdb"; m_pIASMdb = sysWow64Path; m_pIASMdb += L"\\ias\\ias.mdb"; m_pIASOldMdb = sysWow64Path; m_pIASOldMdb += L"\\ias\\iasold.mdb"; } else { // check the error message DWORD error = GetLastError(); if (ERROR_CALL_NOT_IMPLEMENTED == error) { // Pure 32 bits environment uReturn = GetWindowsDirectoryW(sysWow64Path, MAX_PATH); if ( uReturn != 0 ) { // proper path found m_pIASNewMdb = sysWow64Path; m_pIASNewMdb += L"\\System32\\ias\\iasnew.mdb"; m_pIASMdb = sysWow64Path; m_pIASMdb += L"\\System32\\ias\\ias.mdb"; m_pIASOldMdb = sysWow64Path; m_pIASOldMdb += L"\\System32\\ias\\iasold.mdb"; } else { _com_issue_error(HRESULT_FROM_WIN32(error)); } } else { _com_issue_error(HRESULT_FROM_WIN32(error)); } } /////////////////////////////////////////////// // Check that all the strings are properly set /////////////////////////////////////////////// if ( !m_pIASNewMdb || !m_pIASMdb || !m_pIASOldMdb ) { _com_issue_error(E_OUTOFMEMORY); } } ///////////////////////////////// // CIASUpgrade::GetVersionNumber ///////////////////////////////// LONG CIASUpgrade::GetVersionNumber(LPCWSTR DatabaseName) { if ( !DatabaseName ) { _com_issue_error(E_INVALIDARG); } ///////////////////////////////////////////////// // Check %TMP% and create a directory if needed // That's to fix a bug with JET ///////////////////////////////////////////////// IASCreateTmpDirectory(); CComPtr Session = NULL; HRESULT hr = IASOpenJetDatabase(DatabaseName, TRUE, &Session); if ( FAILED(hr) ) { _com_issue_error(hr); } CComBSTR SelectVersion(L"SELECT * FROM Version"); if ( !SelectVersion ) { _com_issue_error(E_OUTOFMEMORY); } LONG Version = 0; hr = IASExecuteSQLFunction(Session, SelectVersion, &Version); if ( FAILED(hr) ) // no Version table for instance { // Version 0. That's not an error } Session.Release(); return Version; } /////////////////////////////////////////////////////////////// // CIASUpgrade::DoWin2kUpgradeFromNetshell // // The call to the upgrade is the result of a Netshell script // ias.mdb is assumed present and good (Whistler). // iasold is assumed present and will be migrated into ias.mdb /////////////////////////////////////////////////////////////// void CIASUpgrade::DoWin2kUpgradeFromNetshell() { /////////////////////////////////////////////////////// // Now Upgrade the Win2k, Whistler 1.0 or Whistler 2.0 // DB into the current Whistler 2.0 DB // The upgrade will throw if it fails /////////////////////////////////////////////////////// { CUpgradeWin2k Upgrade2k; Upgrade2k.Execute(); } //////////////////////////////////// // Delete iasold.mdb no matter what // here the upgrade was successful //////////////////////////////////// DeleteFile(m_pIASOldMdb); } ////////////////////////////////////////////////// // DoNT4UpgradeOrCleanInstall // // The file ias.mdb did not exist before // That's either a NT4 upgrade or a clean install // iasnew.mdb was successfuly copied into ias.mdb ////////////////////////////////////////////////// void CIASUpgrade::DoNT4UpgradeOrCleanInstall() { //////////////////////////////////// // Delete iasnew.mdb no matter what //////////////////////////////////// DeleteFile(m_pIASNewMdb); ////////////////////////////////////////////////////// // Call DoUpgrade: that will check if a NT4 migration // should be done or not and do it if necessary ////////////////////////////////////////////////////// CDoNT4OrCleanUpgrade Upgrade; Upgrade.Execute(); } ///////////////////////////////////////////////////////////////////////////// // CIASUpgrade::DoWin2kUpgrade ///////////////////////////////////////////////////////////////////////////// void CIASUpgrade::DoWin2kUpgrade() { LONG Result = ERROR_SUCCESS; ////////////////////////////////////////// // now force copy ias.mdb into iasold.mdb ////////////////////////////////////////// BOOL Succeeded = CopyFile(m_pIASMdb, m_pIASOldMdb, FALSE); if ( !Succeeded ) { //////////////////////////////////////////////// // iasnew.mdb will still be copied into ias.mdb // later but not upgraded after that //////////////////////////////////////////////// Result = GetLastError(); } ////////////////////////////////////// // force copy iasnew.mdb into ias.mdb ////////////////////////////////////// Succeeded = CopyFile(m_pIASNewMdb, m_pIASMdb, FALSE); if ( !Succeeded ) { ///////////////////////////// // do not upgrade after that ///////////////////////////// Result = GetLastError(); } //////////////////////////////////////////////////// // Delete iasnew.mdb no matter what: if the upgrade // throws an exception then iasnew.mdb will not be // left on the drive //////////////////////////////////////////////////// DeleteFile(m_pIASNewMdb); ///////////////////////////////////////////// // Now Upgrade the Win2k or Whistler 1.0 DB // into the Whistler DB if the previous copy // operations were successful ///////////////////////////////////////////// if ( Result == ERROR_SUCCESS ) { /////////////////////////////////// // will throw if the upgrade fails /////////////////////////////////// CUpgradeWin2k Upgrade2k; Upgrade2k.Execute(); } else { _com_issue_error(HRESULT_FROM_WIN32(Result)); } //////////////////////////////////// // Delete iasold.mdb no matter what // here the upgrade was successful //////////////////////////////////// DeleteFile(m_pIASOldMdb); } //////////////////////////////////////// // CIASUpgrade::DoWhistlerUpgrade // // nothing to do: already a Whistler DB //////////////////////////////////////// void CIASUpgrade::DoWhistlerUpgrade() { //////////////////////////////////// // Delete iasnew.mdb no matter what //////////////////////////////////// DeleteFile(m_pIASNewMdb); } ///////////////////////////////////////////////////////////////////////////// // CIASUpgrade::IASUpgrade ///////////////////////////////////////////////////////////////////////////// HRESULT CIASUpgrade::IASUpgrade(BOOL FromNetshell) { HRESULT hr = S_OK; //////////////////////////// // Now get the upgrade type //////////////////////////// do { if ( FromNetshell ) { UpgradeType = Win2kUpgradeFromNetshell; break; } /////////////////////////////////////// // try to copy iasnew.mdb into ias.mdb // fails if the file is already there /////////////////////////////////////// BOOL IsNT4OrCleanInstall = CopyFile(m_pIASNewMdb, m_pIASMdb, TRUE); if ( IsNT4OrCleanInstall ) { // select NT4 or Clean install UpgradeType = NT4UpgradeOrCleanInstall; break; } else // Win2k or Whistler upgrade { /////////////////////////////////////////// // cannot copy: the file is already there. // Check the version number (of ias.mdb) /////////////////////////////////////////// LONG CurrentVersion = GetVersionNumber(m_pIASMdb); const LONG IAS_5_1_VERSION = 3; if ( CurrentVersion < IAS_5_1_VERSION ) { UpgradeType = Win2kUpgrade; break; } else { UpgradeType = WhistlerUpgrade; break; } } } while (FALSE); try { switch ( UpgradeType ) { case Win2kUpgradeFromNetshell: { DoWin2kUpgradeFromNetshell(); break; } case NT4UpgradeOrCleanInstall: { DoNT4UpgradeOrCleanInstall(); break; } case Win2kUpgrade: { DoWin2kUpgrade(); break; } case WhistlerUpgrade: { DoWhistlerUpgrade(); break; } default: { _com_issue_error(E_FAIL); } } } catch(const _com_error& e) { hr = e.Error(); } catch(...) { hr = HRESULT_FROM_WIN32(GetLastError()); } if ( FromNetshell ) { ///////////////////////////////////// // Return the error code to netshell ///////////////////////////////////// return hr; } else { /////////////////////////////////////// // Result ignored: no errors returned. /////////////////////////////////////// return S_OK; } }