Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

374 lines
11 KiB

/////////////////////////////////////////////////////////////////////////////
//
// Copyright(C) Microsoft Corporation all rights reserved.
//
// Module: setup.cpp
//
// Description: IAS MigrateOrUpgrade class implementation
//
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "doupgrade.h"
#include "iasdb.h"
#include "setup.h" // to get the CIASMigrateOrUpgrade class
#include "ias.h"
#include "CheckLicense.h"
////////////////////////////
// CIASMigrateOrUpgrade Constructor
////////////////////////////
CIASMigrateOrUpgrade::CIASMigrateOrUpgrade()
{
///////////////////////////////////////////////////////////////
// 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);
}
}
/////////////////////////////////
// CIASMigrateOrUpgrade::GetVersionNumber
/////////////////////////////////
LONG CIASMigrateOrUpgrade::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;
}
///////////////////////////////////////////////////////////////
// CIASMigrateOrUpgrade::DoNetshellDataMigration
// Reads as "Do Netshell Data Migration"
//
// 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 CIASMigrateOrUpgrade::DoNetshellDataMigration(
IAS_SHOW_TOKEN_LIST configType
)
{
CheckLicense(m_pIASOldMdb, configType);
///////////////////////////////////////////////////////
// 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
///////////////////////////////////////////////////////
{
CMigrateOrUpgradeWindowsDB Upgrade(configType);
Upgrade.Execute();
}
}
//////////////////////////////////////////////////
// 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 CIASMigrateOrUpgrade::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();
}
/////////////////////////////////////////////////////////////////////////////
// CIASMigrateOrUpgrade::DoWin2000Upgrade
/////////////////////////////////////////////////////////////////////////////
void CIASMigrateOrUpgrade::DoWin2000Upgrade()
{
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
///////////////////////////////////
CMigrateOrUpgradeWindowsDB 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);
}
////////////////////////////////////////
// CIASMigrateOrUpgrade::DoXPOrDotNetUpgrade
//
// nothing to do: already a Whistler DB
////////////////////////////////////////
void CIASMigrateOrUpgrade::DoXPOrDotNetUpgrade()
{
////////////////////////////////////
// Delete iasnew.mdb no matter what
////////////////////////////////////
DeleteFile(m_pIASNewMdb);
}
/////////////////////////////////////////////////////////////////////////////
// CIASMigrateOrUpgrade::Execute
/////////////////////////////////////////////////////////////////////////////
HRESULT CIASMigrateOrUpgrade::Execute(
BOOL FromNetshell,
IAS_SHOW_TOKEN_LIST configType
)
{
HRESULT hr = S_OK;
////////////////////////////
// Now get the upgrade type
////////////////////////////
do
{
if ( FromNetshell )
{
m_migrateType = NetshellDataMigration;
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
m_migrateType = 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);
if ( CurrentVersion < IAS_CURRENT_VERSION )
{
m_migrateType = Win2kUpgrade;
break;
}
else
{
m_migrateType = XPOrDotNetUpgrade;
break;
}
}
}
while (FALSE);
try
{
switch ( m_migrateType )
{
case NetshellDataMigration:
{
DoNetshellDataMigration(configType);
break;
}
case NT4UpgradeOrCleanInstall:
{
DoNT4UpgradeOrCleanInstall();
break;
}
case Win2kUpgrade:
{
DoWin2000Upgrade();
break;
}
case XPOrDotNetUpgrade:
{
DoXPOrDotNetUpgrade();
break;
}
default:
{
_com_issue_error(E_FAIL);
}
}
}
catch(const _com_error& e)
{
hr = e.Error();
}
catch(...)
{
hr = HRESULT_FROM_WIN32(GetLastError());
}
if ( FromNetshell )
{
// From net shell, we never want to leave the temporary mdb -- even if we
// failed.
DeleteFile(m_pIASOldMdb);
/////////////////////////////////////
// Return the error code to netshell
/////////////////////////////////////
return hr;
}
else
{
///////////////////////////////////////
// Result ignored: no errors returned.
///////////////////////////////////////
return S_OK;
}
}