377 lines
10 KiB
C++
377 lines
10 KiB
C++
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// 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<IUnknown> 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;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|