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.
1740 lines
42 KiB
1740 lines
42 KiB
//=--------------------------------------------------------------------------=
|
|
// inseng.cpp
|
|
//=--------------------------------------------------------------------------=
|
|
// Copyright 1995-1996 Microsoft Corporation. All Rights Reserved.
|
|
//
|
|
//
|
|
#include "inspch.h"
|
|
#include "regstr.h"
|
|
#include "globals.h"
|
|
#include "insobj.h"
|
|
#include "resource.h"
|
|
#include "diskspac.h"
|
|
|
|
#define GRPCONV "grpconv -o"
|
|
|
|
#define BUFFERSIZE 4096
|
|
|
|
|
|
|
|
//=--------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=--------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
CInstallEngine::CInstallEngine(IUnknown **punk)
|
|
{
|
|
DWORD dwThreadID;
|
|
HANDLE hThread;
|
|
HKEY hKey = NULL;
|
|
char szBuf[16];
|
|
DWORD dwType;
|
|
|
|
GetWindowsDirectory(g_szWindowsDir, sizeof(g_szWindowsDir));
|
|
if(g_szWindowsDir[0] >= 'a' && g_szWindowsDir[0] <= 'z')
|
|
g_szWindowsDir[0] -= 32;
|
|
|
|
hThread = CreateThread(NULL, 0, CleanUpAllDirs, NULL, 0, &dwThreadID);
|
|
CloseHandle(hThread);
|
|
_chInsDrive = g_szWindowsDir[0];
|
|
|
|
// Decide whether we are in stepping mode or not
|
|
_uCommandMode = 0;
|
|
_fSteppingMode = FALSE;
|
|
_fResetTrust = TRUE;
|
|
_fIgnoreTrust = FALSE;
|
|
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, ACTIVESETUP_KEY,0, KEY_READ | KEY_WRITE, &hKey) == ERROR_SUCCESS)
|
|
{
|
|
// Get Steeping mode value. OK if not present
|
|
DWORD dwSize = sizeof(szBuf);
|
|
if(RegQueryValueEx(hKey, STEPPING_VALUE, NULL, &dwType, (LPBYTE) szBuf, &dwSize) == ERROR_SUCCESS)
|
|
{
|
|
if(szBuf[0] == 'y' || szBuf[0] == 'Y')
|
|
_fSteppingMode = TRUE;
|
|
}
|
|
|
|
// Get CommandMode value. OK if not present
|
|
dwSize = sizeof(szBuf);
|
|
if(RegQueryValueEx(hKey, COMMAND_VALUE, NULL, &dwType, (LPBYTE) szBuf, &dwSize) == ERROR_SUCCESS)
|
|
{
|
|
_uCommandMode = AtoL(szBuf);
|
|
// Once we read it, set it to zero
|
|
// BUGBUG: beware of hardcoded "0" and 2 below (2 includes null terminator)
|
|
RegSetValueEx(hKey, COMMAND_VALUE, 0, REG_SZ, (BYTE *) "0", 2 );
|
|
}
|
|
|
|
if(RegQueryValueEx(hKey, CHECKTRUST_VALUE, NULL, &dwType, (LPBYTE) szBuf, &dwSize) == ERROR_SUCCESS)
|
|
{
|
|
if(szBuf[0] == 'Y' || szBuf[0] == 'y')
|
|
{
|
|
_fIgnoreTrust = TRUE;
|
|
_fResetTrust = FALSE;
|
|
}
|
|
// Once we read it, set it to zero
|
|
// BUGBUG: beware of hardcoded "0" and 2 below (2 includes null terminator)
|
|
RegDeleteValue(hKey, CHECKTRUST_VALUE);
|
|
}
|
|
|
|
|
|
RegCloseKey(hKey);
|
|
}
|
|
|
|
_hwndForUI = NULL;
|
|
_pStmLog = NULL;
|
|
_fIgnoreDownloadError = FALSE;
|
|
_enginestatus = ENGINESTATUS_NOTREADY;
|
|
_dwStatus = 0;
|
|
_pcb = NULL;
|
|
_cRef = 0;
|
|
_dwDLRemaining = 0;
|
|
_dwInstallRemaining = 0;
|
|
_dwInstallOld = 0;
|
|
_dwDLOld = 0;
|
|
_fUseCache = FALSE;
|
|
_dwInstallOptions = INSTALLOPTIONS_DOWNLOAD | INSTALLOPTIONS_INSTALL;
|
|
_hContinue = NULL;
|
|
_hAbort = NULL;
|
|
_fCleanUpDir = FALSE;
|
|
//init CCifFile
|
|
_pCif = new CCifFile();
|
|
_pCif->AddRef();
|
|
_pCif->SetInstallEngine(this);
|
|
// init downloader
|
|
_pDL = new CDownloader();
|
|
_pIns = new CInstaller(this);
|
|
|
|
_szBaseUrl[0] = 0;
|
|
|
|
_fSRLiteAvailable = IsPatchableIEVersion() && IsCorrectAdvpExt() && InitSRLiteLibs();
|
|
if (!_fSRLiteAvailable)
|
|
WriteToLog("Install engine failed to initialize the advpack extension DLL\r\n", FALSE);
|
|
|
|
_pPDL = new CPatchDownloader(_fSRLiteAvailable);
|
|
|
|
AddRef();
|
|
*punk = (IInstallEngine *) this;
|
|
}
|
|
|
|
//=--------------------------------------------------------------------------=
|
|
// CInstallEngine::~CInstallEngine
|
|
//=--------------------------------------------------------------------------=
|
|
// Destructor for InstallEngine class
|
|
//
|
|
// Parameters:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
CInstallEngine::~CInstallEngine()
|
|
{
|
|
char szBuf[MAX_PATH];
|
|
|
|
WriteToLog("Install Engine - object destroyed\r\n", TRUE);
|
|
|
|
if(_fCleanUpDir)
|
|
{
|
|
lstrcpy(szBuf, _pCif->GetDownloadDir());
|
|
}
|
|
|
|
if(_hAbort)
|
|
CloseHandle(_hAbort);
|
|
|
|
if(_hContinue)
|
|
CloseHandle(_hContinue);
|
|
|
|
if(_pStmLog)
|
|
_pStmLog->Release();
|
|
|
|
_pcb = NULL;
|
|
|
|
_pCif->Release();
|
|
|
|
_pDL->Release();
|
|
|
|
delete _pPDL;
|
|
|
|
_pIns->Release();
|
|
|
|
if(_fCleanUpDir)
|
|
{
|
|
CleanUpTempDir(szBuf);
|
|
}
|
|
|
|
FreeSRLiteLibs();
|
|
|
|
DllRelease();
|
|
}
|
|
|
|
//************ IUnknown implementation ***************
|
|
|
|
//=--------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=--------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
STDMETHODIMP_(ULONG) CInstallEngine::AddRef()
|
|
{
|
|
return(_cRef++);
|
|
}
|
|
|
|
//=--------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=--------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
STDMETHODIMP_(ULONG) CInstallEngine::Release()
|
|
{
|
|
ULONG temp = --_cRef;
|
|
|
|
if(temp == 0)
|
|
delete this;
|
|
return temp;
|
|
}
|
|
|
|
//=--------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=--------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
STDMETHODIMP CInstallEngine::QueryInterface(REFIID riid, void **ppv)
|
|
{
|
|
*ppv = NULL;
|
|
|
|
if((riid == IID_IUnknown) || (riid == IID_IInstallEngine))
|
|
*ppv = (IInstallEngine *)this;
|
|
else if(riid == IID_IInstallEngineTiming)
|
|
*ppv = (IInstallEngineTiming *)this;
|
|
else if(riid == IID_IInstallEngine2)
|
|
*ppv = (IInstallEngine2 *)this;
|
|
|
|
|
|
if(*ppv == NULL)
|
|
return E_NOINTERFACE;
|
|
|
|
AddRef();
|
|
return NOERROR;
|
|
}
|
|
|
|
//************* IInstallEngine interface ************
|
|
|
|
//=--------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=--------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
STDMETHODIMP CInstallEngine::SetLocalCif(LPCSTR pszCifPath)
|
|
{
|
|
HCURSOR hNew = NULL;
|
|
HCURSOR hOld = NULL;
|
|
|
|
OnEngineStatusChange(ENGINESTATUS_LOADING, 0);
|
|
|
|
hNew = LoadCursor(NULL, IDC_WAIT);
|
|
hOld = SetCursor(hNew);
|
|
|
|
HRESULT hr = _pCif->SetCifFile(pszCifPath, FALSE);
|
|
if(SUCCEEDED(hr))
|
|
OnEngineStatusChange(ENGINESTATUS_READY, 0);
|
|
else
|
|
OnEngineStatusChange(ENGINESTATUS_NOTREADY, hr);
|
|
|
|
SetCursor(hOld);
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CInstallEngine::GetICifFile(ICifFile **pic)
|
|
{
|
|
*pic = (ICifFile *) _pCif;
|
|
(*pic)->AddRef();
|
|
return NOERROR;
|
|
}
|
|
|
|
STDMETHODIMP CInstallEngine::GetEngineStatus(DWORD * theenginestatus)
|
|
{
|
|
*theenginestatus = _enginestatus;
|
|
return(NOERROR);
|
|
}
|
|
|
|
//=--------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=--------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
STDMETHODIMP CInstallEngine::Abort(DWORD lFlag)
|
|
{
|
|
// If we are NOT downLOADING or INSTALLING, an abort command makes no sense.
|
|
if( !(_enginestatus == ENGINESTATUS_INSTALLING || _enginestatus == ENGINESTATUS_LOADING) )
|
|
return E_UNEXPECTED;
|
|
|
|
// if we are downloading, this will cause the abort to filter thru
|
|
_pDL->Abort();
|
|
|
|
// this will abort an install if possible
|
|
_pIns->Abort();
|
|
|
|
// any other time, we will pick this up just as soon as we can
|
|
SetEvent(_hAbort);
|
|
|
|
WriteToLog("Install Engine - Abort called\r\n", FALSE);
|
|
|
|
return(NOERROR);
|
|
}
|
|
|
|
|
|
//=--------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=--------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
STDMETHODIMP CInstallEngine::Suspend()
|
|
{
|
|
HRESULT hr;
|
|
|
|
if(_enginestatus != ENGINESTATUS_INSTALLING)
|
|
return E_UNEXPECTED;
|
|
|
|
WriteToLog("Install Engine - Suspend called\r\n", FALSE);
|
|
|
|
|
|
_pDL->Suspend();
|
|
|
|
// we only catch suspend return, because it tells us "zsafe to cancel or not"
|
|
hr = _pIns->Suspend();
|
|
|
|
ResetEvent(_hContinue);
|
|
|
|
// If we cant create the resume event, we will fail this call and not pause
|
|
|
|
return hr;
|
|
}
|
|
|
|
//=--------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=--------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
STDMETHODIMP CInstallEngine::Resume()
|
|
{
|
|
if(_enginestatus != ENGINESTATUS_INSTALLING)
|
|
return E_UNEXPECTED;
|
|
|
|
WriteToLog("Install Engine - Resume called\r\n", FALSE);
|
|
|
|
_pDL->Resume();
|
|
|
|
_pIns->Resume();
|
|
|
|
SetEvent(_hContinue);
|
|
|
|
return NOERROR;
|
|
}
|
|
//=--------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=--------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
STDMETHODIMP CInstallEngine::SetCifFile(LPCSTR pszCabName, LPCSTR pszCifName)
|
|
{
|
|
HRESULT hr = NOERROR;
|
|
HANDLE hThread;
|
|
DWORD dwThreadID;
|
|
|
|
if(_enginestatus == ENGINESTATUS_LOADING || _enginestatus == ENGINESTATUS_INSTALLING)
|
|
return E_UNEXPECTED;
|
|
|
|
SETCIFARGS *p = new SETCIFARGS;
|
|
|
|
if (p == NULL)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
goto Cleanup;
|
|
}
|
|
|
|
if(_szBaseUrl[0] != 0)
|
|
{
|
|
if (lstrlen(_szBaseUrl) + lstrlen(pszCabName) + 2 > INTERNET_MAX_URL_LENGTH)
|
|
{
|
|
hr = E_INVALIDARG;
|
|
goto Cleanup;
|
|
}
|
|
|
|
p->szUrl[0] = '\0';
|
|
lstrcpy(p->szUrl, _szBaseUrl);
|
|
lstrcat(p->szUrl, "/");
|
|
lstrcat(p->szUrl, pszCabName);
|
|
}
|
|
else
|
|
{
|
|
lstrcpy(p->szUrl, "file://");
|
|
lstrcat(p->szUrl, _pCif->GetDownloadDir());
|
|
SafeAddPath(p->szUrl, pszCabName, sizeof(p->szUrl));
|
|
}
|
|
|
|
lstrcpyn(p->szCif, pszCifName, MAX_PATH);
|
|
|
|
p->pCif = _pCif;
|
|
|
|
// do the actual downloading of the CIF file in a separate thread
|
|
if ((hThread = CreateThread(NULL, 0, DownloadCifFile, (LPVOID) p, 0, &dwThreadID)) != NULL)
|
|
CloseHandle(hThread);
|
|
else
|
|
{
|
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
|
}
|
|
|
|
Cleanup:
|
|
|
|
if (FAILED(hr) && p != NULL)
|
|
delete p;
|
|
|
|
return hr;
|
|
}
|
|
|
|
//=--------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=--------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
STDMETHODIMP CInstallEngine::SetBaseUrl(LPCSTR pszBaseName)
|
|
{
|
|
DWORD dwLen;
|
|
|
|
if(_enginestatus == ENGINESTATUS_INSTALLING)
|
|
if(!_IsValidBaseUrl(pszBaseName))
|
|
return E_UNEXPECTED;
|
|
|
|
lstrcpyn(_szBaseUrl, pszBaseName, INTERNET_MAX_URL_LENGTH);
|
|
|
|
wsprintf(szLogBuf,"Install Engine - base url set to %s\r\n", pszBaseName);
|
|
WriteToLog(szLogBuf, FALSE);
|
|
|
|
return NOERROR;
|
|
}
|
|
|
|
|
|
//=--------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=--------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
STDMETHODIMP CInstallEngine::SetDownloadDir(LPCSTR pszDLDir)
|
|
{
|
|
char szBuf[MAX_PATH];
|
|
DWORD dwLen;
|
|
DWORD dwVer;
|
|
|
|
if(_enginestatus == ENGINESTATUS_INSTALLING)
|
|
return E_UNEXPECTED;
|
|
|
|
if(pszDLDir != NULL && lstrlen(pszDLDir) > (MAX_PATH - 20))
|
|
return E_FAIL;
|
|
|
|
// clean up what we have
|
|
if(_fCleanUpDir)
|
|
{
|
|
DelNode(_pCif->GetDownloadDir(), 0);
|
|
_fCleanUpDir = FALSE;
|
|
}
|
|
|
|
if(pszDLDir == NULL)
|
|
{
|
|
_fCleanUpDir = TRUE;
|
|
if(FAILED(CreateTempDirOnMaxDrive(szBuf, sizeof(szBuf))))
|
|
return E_FAIL;
|
|
}
|
|
else
|
|
{
|
|
_fCleanUpDir = FALSE;
|
|
// Make sure the directory exists
|
|
if(GetFileAttributes(pszDLDir) == 0xffffffff)
|
|
CreateDirectory(pszDLDir, NULL);
|
|
}
|
|
|
|
_pCif->SetDownloadDir(pszDLDir ? pszDLDir : szBuf);
|
|
|
|
wsprintf(szLogBuf,"Install Engine - download directory set to %s\r\n", _pCif->GetDownloadDir());
|
|
WriteToLog(szLogBuf, FALSE);
|
|
|
|
return NOERROR;
|
|
}
|
|
|
|
|
|
|
|
//=--------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=--------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
STDMETHODIMP CInstallEngine::IsComponentInstalled(LPCSTR pszComponentID, DWORD *lResult)
|
|
{
|
|
DWORD dwResult = ICI_NOTINSTALLED;
|
|
|
|
ICifComponent *pComp = NULL;
|
|
|
|
if(SUCCEEDED(_pCif->FindComponent(pszComponentID, &pComp)))
|
|
{
|
|
dwResult = pComp->IsComponentInstalled();
|
|
}
|
|
|
|
*lResult = dwResult;
|
|
|
|
return(pComp ? NOERROR : E_INVALIDARG);
|
|
}
|
|
|
|
|
|
STDMETHODIMP CInstallEngine::SetInstallDrive(CHAR chDrive)
|
|
{
|
|
HRESULT hr = E_INVALIDARG;
|
|
|
|
if(chDrive >= 'a' && chDrive <= 'z')
|
|
chDrive -= 32;
|
|
|
|
if(chDrive >= 'A' && chDrive <= 'Z')
|
|
{
|
|
hr = NOERROR;
|
|
_chInsDrive = chDrive;
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
//=---------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=---------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
STDMETHODIMP CInstallEngine::SetInstallOptions(DWORD dwOptions)
|
|
{
|
|
_fUseCache = !(dwOptions & INSTALLOPTIONS_NOCACHE);
|
|
_dwInstallOptions = dwOptions;
|
|
return NOERROR;
|
|
}
|
|
|
|
//=---------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=---------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
STDMETHODIMP CInstallEngine::GetInstallOptions(DWORD *pdwOptions)
|
|
{
|
|
if (!pdwOptions)
|
|
return E_POINTER;
|
|
else
|
|
{
|
|
*pdwOptions = _dwInstallOptions;
|
|
return NOERROR;
|
|
}
|
|
}
|
|
|
|
//=---------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=---------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
STDMETHODIMP CInstallEngine::GetSizes(LPCSTR pszID, COMPONENT_SIZES *p)
|
|
{
|
|
if(!p)
|
|
return E_POINTER;
|
|
|
|
// work around bug in old versions of jobexec where it didn't init
|
|
// this field properly
|
|
|
|
if(p->cbSize > sizeof(COMPONENT_SIZES))
|
|
p->cbSize = COMPONENTSIZES_SIZE_V1;
|
|
|
|
DWORD dwSize = p->cbSize;
|
|
ZeroMemory(p, p->cbSize);
|
|
p->cbSize = dwSize;
|
|
|
|
if(_enginestatus != ENGINESTATUS_READY)
|
|
return E_UNEXPECTED;
|
|
|
|
if(pszID != NULL)
|
|
{
|
|
ICifComponent *pComp = NULL;
|
|
|
|
if(SUCCEEDED(_pCif->FindComponent(pszID, &pComp)))
|
|
{
|
|
DWORD dwWin, dwApp;
|
|
p->dwDownloadSize = pComp->GetDownloadSize();
|
|
pComp->GetInstalledSize(&dwWin, &dwApp);
|
|
p->dwInstallSize = dwApp;
|
|
p->dwWinDriveSize = dwWin;
|
|
}
|
|
else
|
|
return E_INVALIDARG;
|
|
}
|
|
else
|
|
_GetTotalSizes(p);
|
|
|
|
return NOERROR;
|
|
}
|
|
|
|
//=---------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=---------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
|
|
void CInstallEngine::_GetTotalSizes(COMPONENT_SIZES *pSizes)
|
|
{
|
|
ICifComponent *pComp;
|
|
DriveInfo drvinfo[3];
|
|
LPSTR pszDep = NULL;
|
|
UINT uTempDrive;
|
|
UINT uWinDrive = 0;
|
|
UINT uInstallDrive = 1;
|
|
UINT uDownloadDrive = 2;
|
|
LPCSTR pszDownloadDir = _pCif->GetDownloadDir();
|
|
COMPONENT_SIZES Sizes;
|
|
|
|
ZeroMemory(&Sizes, sizeof(COMPONENT_SIZES));
|
|
|
|
// Fill in all arrays to start
|
|
|
|
drvinfo[uWinDrive].InitDrive(g_szWindowsDir[0]);
|
|
|
|
if(_dwInstallOptions & INSTALLOPTIONS_INSTALL)
|
|
{
|
|
// We know we can do a compare because these are always uppcase
|
|
if(_chInsDrive != drvinfo[uWinDrive].Drive())
|
|
{
|
|
drvinfo[uInstallDrive].InitDrive(_chInsDrive);
|
|
}
|
|
else
|
|
uInstallDrive = uWinDrive;
|
|
}
|
|
|
|
if(_dwInstallOptions & INSTALLOPTIONS_DOWNLOAD)
|
|
{
|
|
if(pszDownloadDir[0] == drvinfo[uWinDrive].Drive())
|
|
uDownloadDrive = uWinDrive;
|
|
else if(pszDownloadDir[0] == drvinfo[uInstallDrive].Drive())
|
|
uDownloadDrive = uInstallDrive;
|
|
else
|
|
drvinfo[uDownloadDrive].InitDrive(pszDownloadDir[0]);
|
|
}
|
|
|
|
// do space for download phase (easy part)
|
|
if(_dwInstallOptions & INSTALLOPTIONS_DOWNLOAD)
|
|
{
|
|
Sizes.dwDownloadSize = _GetActualDownloadSize(FALSE);
|
|
Sizes.dwTotalDownloadSize = _GetTotalDownloadSize();
|
|
Sizes.dwDependancySize = 0;
|
|
|
|
// add download to download drive
|
|
drvinfo[uDownloadDrive].UseSpace(Sizes.dwDownloadSize + Sizes.dwDependancySize, TRUE);
|
|
|
|
// if going to cache
|
|
// BUGBUG: we still assume cache is on windows drive
|
|
if(_fUseCache)
|
|
{
|
|
drvinfo[uWinDrive].UseSpace(Sizes.dwDownloadSize + Sizes.dwDependancySize, TRUE);
|
|
}
|
|
}
|
|
|
|
// do space for install (hard part)
|
|
if(_dwInstallOptions & INSTALLOPTIONS_INSTALL)
|
|
{
|
|
// walk the install list in order (very important)
|
|
// do any dependancy, then original
|
|
IEnumCifComponents *penum;
|
|
ICifComponent *pComp = NULL;
|
|
|
|
_pCif->EnumComponents(&penum, 0, NULL);
|
|
for(penum->Next(&pComp); pComp; penum->Next(&pComp))
|
|
{
|
|
if(pComp->GetInstallQueueState() == SETACTION_INSTALL)
|
|
{
|
|
DWORD dwWin, dwApp;
|
|
|
|
pComp->GetInstalledSize(&dwWin, &dwApp);
|
|
// add install
|
|
// add the install size
|
|
Sizes.dwInstallSize += dwApp;
|
|
// size that goes to windows dir
|
|
Sizes.dwWinDriveSize += dwWin;
|
|
|
|
drvinfo[uInstallDrive].UseSpace(dwApp, FALSE);
|
|
drvinfo[uWinDrive].UseSpace(dwWin, FALSE);
|
|
// Add (and then remove) temp space
|
|
AddTempSpace(pComp->GetDownloadSize(), pComp->GetExtractSize(), drvinfo);
|
|
|
|
|
|
}
|
|
}
|
|
penum->Release();
|
|
}
|
|
|
|
// fill in the required amounts
|
|
Sizes.dwWinDriveReq = drvinfo[uWinDrive].MaxUsed();
|
|
Sizes.chWinDrive = drvinfo[uWinDrive].Drive();
|
|
|
|
if(uWinDrive != uInstallDrive)
|
|
{
|
|
Sizes.dwInstallDriveReq = drvinfo[uInstallDrive].MaxUsed();
|
|
Sizes.chInstallDrive = drvinfo[uInstallDrive].Drive();
|
|
}
|
|
if((uDownloadDrive != uWinDrive) && (uDownloadDrive != uInstallDrive))
|
|
{
|
|
Sizes.dwDownloadDriveReq = drvinfo[uDownloadDrive].MaxUsed();
|
|
Sizes.chDownloadDrive = drvinfo[uDownloadDrive].Drive();
|
|
}
|
|
|
|
CopyMemory((LPVOID)(&(pSizes->dwInstallSize)), (LPVOID)(&(Sizes.dwInstallSize)),
|
|
pSizes->cbSize - sizeof(DWORD));
|
|
}
|
|
|
|
|
|
//=---------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=---------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
STDMETHODIMP CInstallEngine::SetAction(LPCSTR pszComponentID, DWORD action, DWORD dwPriority)
|
|
{
|
|
HRESULT hr = NOERROR;
|
|
|
|
if(_enginestatus != ENGINESTATUS_READY)
|
|
return E_UNEXPECTED;
|
|
|
|
ICifComponent *pComp = NULL;
|
|
|
|
if(pszComponentID == NULL || lstrlen(pszComponentID) == 0)
|
|
{
|
|
_pCif->ClearQueueState();
|
|
}
|
|
else
|
|
{
|
|
if(SUCCEEDED(_pCif->FindComponent(pszComponentID, &pComp)))
|
|
{
|
|
if(dwPriority != 0xffffffff)
|
|
pComp->SetCurrentPriority(dwPriority);
|
|
hr = pComp->SetInstallQueueState(action);
|
|
}
|
|
else
|
|
hr = E_INVALIDARG;
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
// the following two are now ridiculously inefficient. New clients should use the enumerators
|
|
|
|
STDMETHODIMP CInstallEngine::EnumInstallIDs(UINT uIndex, LPSTR *ppszID)
|
|
{
|
|
HRESULT hr;
|
|
UINT i = 0;
|
|
*ppszID = NULL;
|
|
|
|
IEnumCifComponents *penum;
|
|
ICifComponent *pComp;
|
|
|
|
_pCif->EnumComponents(&penum, 0, NULL);
|
|
for(penum->Next(&pComp); pComp; penum->Next(&pComp))
|
|
{
|
|
if(pComp->GetInstallQueueState())
|
|
{
|
|
if(uIndex == i)
|
|
break;
|
|
i++;
|
|
}
|
|
}
|
|
penum->Release();
|
|
if(pComp)
|
|
{
|
|
char szID[MAX_ID_LENGTH];
|
|
pComp->GetID(szID, sizeof(szID));
|
|
*ppszID = COPYANSISTR(szID);
|
|
hr = NOERROR;
|
|
}
|
|
else
|
|
hr = E_FAIL;
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
STDMETHODIMP CInstallEngine::EnumDownloadIDs(UINT uIndex, LPSTR *ppszID)
|
|
{
|
|
HRESULT hr;
|
|
UINT i = 0;
|
|
*ppszID = NULL;
|
|
|
|
IEnumCifComponents *penum;
|
|
ICifComponent *pComp;
|
|
|
|
_pCif->EnumComponents(&penum, 0, NULL);
|
|
for(penum->Next(&pComp); pComp; penum->Next(&pComp))
|
|
{
|
|
if(pComp->GetInstallQueueState() && (pComp->IsComponentDownloaded() == S_FALSE))
|
|
{
|
|
if(uIndex == i)
|
|
break;
|
|
i++;
|
|
}
|
|
}
|
|
penum->Release();
|
|
if(pComp)
|
|
{
|
|
char szID[MAX_ID_LENGTH];
|
|
pComp->GetID(szID, sizeof(szID));
|
|
*ppszID = COPYANSISTR(szID);
|
|
hr = NOERROR;
|
|
}
|
|
else
|
|
hr = E_FAIL;
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
|
|
//=---------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=---------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
STDMETHODIMP CInstallEngine::DownloadComponents(DWORD lFlags)
|
|
{
|
|
DWORD dwThreadID;
|
|
HRESULT hr = NOERROR;
|
|
|
|
WriteToLog("Install Engine - Starting download phase\r\n", TRUE);
|
|
if(_enginestatus == ENGINESTATUS_NOTREADY || _enginestatus == ENGINESTATUS_LOADING)
|
|
hr = E_UNEXPECTED;
|
|
|
|
// BUGBUG - add a downloading status? it really just a "busy" indication
|
|
if(_enginestatus == ENGINESTATUS_INSTALLING)
|
|
hr = E_PENDING;
|
|
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
OnEngineStatusChange(ENGINESTATUS_INSTALLING, 0);
|
|
|
|
// since trust may be set globally, only turn it on, not off
|
|
if(EXECUTEJOB_IGNORETRUST & lFlags)
|
|
_fIgnoreTrust = TRUE;
|
|
|
|
if(EXECUTEJOB_IGNOREDOWNLOADERROR & lFlags)
|
|
_fIgnoreDownloadError = TRUE;
|
|
else
|
|
_fIgnoreDownloadError = FALSE;
|
|
|
|
HANDLE h = CreateThread(NULL, 0, InitDownloader, this, 0, &dwThreadID);
|
|
if(h == NULL)
|
|
{
|
|
// Won't be doing any downloading today.....
|
|
hr = E_FAIL;
|
|
}
|
|
else
|
|
CloseHandle(h);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//=---------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=---------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
STDMETHODIMP CInstallEngine::InstallComponents(DWORD lFlags)
|
|
{
|
|
DWORD dwThreadID;
|
|
HRESULT hr = NOERROR;
|
|
|
|
WriteToLog("Install Engine - Starting install phase\r\n", TRUE);
|
|
|
|
EnterCriticalSection(&g_cs);
|
|
if(_enginestatus == ENGINESTATUS_NOTREADY || _enginestatus == ENGINESTATUS_LOADING)
|
|
hr = E_UNEXPECTED;
|
|
|
|
if(_enginestatus == ENGINESTATUS_INSTALLING)
|
|
hr = E_PENDING;
|
|
LeaveCriticalSection(&g_cs);
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
// We first check to see if all files are present
|
|
// by seeing if we would download anything!!!
|
|
//
|
|
if(EXECUTEJOB_VERIFYFILES & lFlags)
|
|
{
|
|
WriteToLog("Checking for missing files\r\n", FALSE);
|
|
if(_GetActualDownloadSize(TRUE) != 0)
|
|
return E_FILESMISSING;
|
|
}
|
|
|
|
OnEngineStatusChange(ENGINESTATUS_INSTALLING, 0);
|
|
|
|
// since trust may be set globally, only turn it on, not off
|
|
if(EXECUTEJOB_IGNORETRUST & lFlags)
|
|
_fIgnoreTrust = TRUE;
|
|
|
|
HANDLE h = CreateThread(NULL, 0, InitInstaller, this, 0, &dwThreadID);
|
|
if(h == NULL)
|
|
{
|
|
// Won't be doing any installing today.....
|
|
hr = E_FAIL;
|
|
}
|
|
else
|
|
CloseHandle(h);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//=---------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=---------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
DWORD WINAPI InitInstaller(LPVOID pv)
|
|
{
|
|
CInstallEngine *pInsEng = (CInstallEngine *) pv;
|
|
HRESULT hr = S_OK;
|
|
BOOL fOneInstalled = FALSE;
|
|
|
|
ICifComponent *pComp;
|
|
|
|
EnableSage(FALSE);
|
|
EnableScreenSaver(FALSE);
|
|
EnableDiskCleaner(FALSE);
|
|
|
|
pInsEng->_dwStatus = 0;
|
|
|
|
pInsEng->_hAbort = CreateEvent(NULL, FALSE, FALSE, NULL);
|
|
pInsEng->_hContinue = CreateEvent(NULL, TRUE, TRUE, NULL);
|
|
|
|
//BUGBUG check for failure
|
|
|
|
pInsEng->AddRef();
|
|
|
|
pInsEng->OnStartInstall(0, pInsEng->_GetTotalInstallSize());
|
|
|
|
// check trust the Cif cab if it has not been done so
|
|
hr = pInsEng->CheckForContinue();
|
|
|
|
// this is the install pass
|
|
if(SUCCEEDED(hr))
|
|
hr = pInsEng->_pCif->Install(&fOneInstalled);
|
|
|
|
if(fOneInstalled && FNeedGrpConv())
|
|
{
|
|
if(!(pInsEng->GetStatus() & STOPINSTALL_REBOOTNEEDED))
|
|
{
|
|
// if we dont need a reboot launch grpconv immeadiatly
|
|
HANDLE h = NULL;
|
|
pInsEng->WriteToLog("Install Engine - No reboot required\r\n", FALSE);
|
|
LaunchAndWait(GRPCONV, NULL, &h, NULL, SW_SHOWMINIMIZED);
|
|
if(h)
|
|
CloseHandle(h);
|
|
}
|
|
else
|
|
{
|
|
HKEY hKey;
|
|
DWORD dumb;
|
|
// otherwise put grpconv into runonce
|
|
if(RegCreateKeyEx(HKEY_LOCAL_MACHINE, REGSTR_PATH_RUNONCE,
|
|
0,0,0, KEY_SET_VALUE, NULL, &hKey, &dumb) == ERROR_SUCCESS)
|
|
{
|
|
RegSetValueEx(hKey, "GrpConv", 0, REG_SZ,
|
|
(BYTE *) GRPCONV, sizeof(GRPCONV));
|
|
RegCloseKey(hKey);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// reset to checking trust
|
|
if(pInsEng->_fResetTrust)
|
|
pInsEng->_fIgnoreTrust = FALSE;
|
|
// Send a install all done message
|
|
|
|
if(!(pInsEng->GetStatus() & STOPINSTALL_REBOOTNEEDED))
|
|
{
|
|
// If we don't need a reboot, enable the screen saver and sage.
|
|
EnableScreenSaver(TRUE);
|
|
EnableSage(TRUE);
|
|
}
|
|
EnableDiskCleaner(TRUE);
|
|
|
|
CloseHandle(pInsEng->_hAbort);
|
|
pInsEng->_hAbort = NULL;
|
|
|
|
CloseHandle(pInsEng->_hContinue);
|
|
pInsEng->_hContinue = NULL;
|
|
|
|
|
|
pInsEng->OnStopInstall(hr, NULL, pInsEng->GetStatus());
|
|
pInsEng->OnEngineStatusChange(ENGINESTATUS_READY, 0);
|
|
|
|
pInsEng->Release();
|
|
|
|
|
|
return 0;
|
|
}
|
|
|
|
//=---------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=---------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
DWORD WINAPI InitDownloader(LPVOID pv)
|
|
{
|
|
CInstallEngine *pInsEng = (CInstallEngine *) pv;
|
|
HRESULT hr = S_OK;
|
|
|
|
EnableSage(FALSE);
|
|
EnableScreenSaver(FALSE);
|
|
EnableDiskCleaner(FALSE);
|
|
|
|
pInsEng->_hAbort = CreateEvent(NULL, FALSE, FALSE, NULL);
|
|
pInsEng->_hContinue = CreateEvent(NULL, TRUE, TRUE, NULL);
|
|
|
|
//BUGBUG check for failure
|
|
|
|
pInsEng->AddRef();
|
|
|
|
pInsEng->OnStartInstall(pInsEng->_GetActualDownloadSize(FALSE), 0);
|
|
|
|
// check trust the Cif cab if it has not been done so
|
|
hr = pInsEng->CheckForContinue();
|
|
|
|
// this is the download pass
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
hr = pInsEng->_pCif->Download();
|
|
}
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
pInsEng->WriteToLog("Install Engine - Download complete\r\n", FALSE);
|
|
}
|
|
|
|
// reset to checking trust
|
|
if(pInsEng->_fResetTrust)
|
|
pInsEng->_fIgnoreTrust = FALSE;
|
|
|
|
|
|
CloseHandle(pInsEng->_hAbort);
|
|
pInsEng->_hAbort = NULL;
|
|
|
|
CloseHandle(pInsEng->_hContinue);
|
|
pInsEng->_hContinue = NULL;
|
|
|
|
EnableScreenSaver(TRUE);
|
|
EnableSage(TRUE);
|
|
EnableDiskCleaner(TRUE);
|
|
// Send a install all done message
|
|
EnterCriticalSection(&g_cs);
|
|
pInsEng->OnStopInstall(hr, NULL, 0);
|
|
pInsEng->OnEngineStatusChange(ENGINESTATUS_READY, 0);
|
|
LeaveCriticalSection(&g_cs);
|
|
|
|
pInsEng->Release();
|
|
return 0;
|
|
}
|
|
|
|
|
|
//=---------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=---------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
DWORD CInstallEngine::_GetTotalDownloadSize()
|
|
{
|
|
DWORD dwTotalSize = 0;
|
|
IEnumCifComponents *penum;
|
|
ICifComponent *pComp = NULL;
|
|
|
|
_pCif->EnumComponents(&penum, 0, NULL);
|
|
for(penum->Next(&pComp); pComp; penum->Next(&pComp))
|
|
{
|
|
if(pComp->GetInstallQueueState() == SETACTION_INSTALL)
|
|
dwTotalSize += pComp->GetDownloadSize();
|
|
}
|
|
penum->Release();
|
|
return dwTotalSize;
|
|
}
|
|
|
|
//=---------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=---------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
DWORD CInstallEngine::_GetActualDownloadSize(BOOL bLogMissing)
|
|
{
|
|
DWORD dwTotalSize = 0;
|
|
IEnumCifComponents *penum;
|
|
ICifComponent *pComp = NULL;
|
|
|
|
_pCif->EnumComponents(&penum, 0, NULL);
|
|
for( penum->Next(&pComp); pComp; penum->Next(&pComp))
|
|
{
|
|
if(pComp->GetInstallQueueState() == SETACTION_INSTALL)
|
|
dwTotalSize += pComp->GetActualDownloadSize();
|
|
}
|
|
penum->Release();
|
|
return dwTotalSize;
|
|
}
|
|
|
|
|
|
//=---------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=---------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
DWORD CInstallEngine::_GetTotalInstallSize()
|
|
{
|
|
DWORD dwTotalSize = 0;
|
|
DWORD dwWin, dwApp;
|
|
IEnumCifComponents *penum;
|
|
ICifComponent *pComp = NULL;
|
|
|
|
_pCif->EnumComponents(&penum, 0, NULL);
|
|
for(penum->Next(&pComp); pComp; penum->Next(&pComp))
|
|
{
|
|
if(pComp->GetInstallQueueState() == SETACTION_INSTALL)
|
|
{
|
|
pComp->GetInstalledSize(&dwWin, &dwApp);
|
|
dwTotalSize += (dwWin + dwApp);
|
|
}
|
|
}
|
|
penum->Release();
|
|
return dwTotalSize;
|
|
}
|
|
|
|
|
|
//=---------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=---------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
STDMETHODIMP CInstallEngine::LaunchExtraCommand(LPCSTR pszInfName, LPCSTR pszSection)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
//=---------------------------------------------------------------------------=
|
|
// RegisterInstallEngineCallback
|
|
//=---------------------------------------------------------------------------=
|
|
// Register the callback interface
|
|
//
|
|
// Parameters:
|
|
// IInstallEngineCallback * - the callback interface
|
|
// HWND - For ui
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
STDMETHODIMP CInstallEngine::RegisterInstallEngineCallback(IInstallEngineCallback *pcb)
|
|
{
|
|
_pcb = pcb;
|
|
return NOERROR;
|
|
}
|
|
|
|
//=---------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=---------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
STDMETHODIMP CInstallEngine::UnregisterInstallEngineCallback()
|
|
{
|
|
_pcb = NULL;
|
|
return NOERROR;
|
|
}
|
|
|
|
//=---------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=---------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
STDMETHODIMP CInstallEngine::SetHWND(HWND h)
|
|
{
|
|
_hwndForUI = h;
|
|
return NOERROR;
|
|
}
|
|
|
|
//*********** IInstallEngineCallback implementation ************
|
|
|
|
//=---------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=---------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
STDMETHODIMP CInstallEngine::OnEngineStatusChange(DWORD status,DWORD substatus)
|
|
{
|
|
_enginestatus = status;
|
|
if(_pcb)
|
|
_pcb->OnEngineStatusChange(_enginestatus, substatus);
|
|
return NOERROR;
|
|
}
|
|
|
|
//=---------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=---------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
STDMETHODIMP CInstallEngine::OnStartInstall(DWORD dwDLSize, DWORD dwInstallSize)
|
|
{
|
|
_dwDLRemaining = dwDLSize;
|
|
_dwInstallRemaining = dwInstallSize;
|
|
|
|
wsprintf(szLogBuf, "\r\nOnStartInstall:\r\n Download: %d KB\r\n Install %d KB\r\n", dwDLSize, dwInstallSize);
|
|
WriteToLog(szLogBuf, TRUE);
|
|
|
|
if(_pcb)
|
|
_pcb->OnStartInstall(dwDLSize, dwInstallSize);
|
|
|
|
return NOERROR;
|
|
}
|
|
|
|
//=---------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=---------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
STDMETHODIMP CInstallEngine::OnStartComponent(LPCSTR pszID, DWORD dwDLSize,
|
|
DWORD dwInstallSize, LPCSTR pszString)
|
|
{
|
|
wsprintf(szLogBuf, "OnStartComponent:\r\n ID: %s\r\n Download: %d KB\r\n Install %d KB\r\n",
|
|
pszID, dwDLSize, dwInstallSize);
|
|
WriteToLog(szLogBuf, TRUE);
|
|
|
|
_dwDLOld = 0;
|
|
_dwInstallOld = 0;
|
|
if(_pcb)
|
|
_pcb->OnStartComponent(pszID, dwDLSize, dwInstallSize, pszString);
|
|
|
|
return NOERROR;
|
|
}
|
|
|
|
//=---------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=---------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
STDMETHODIMP CInstallEngine::OnEngineProblem(DWORD dwProblem, LPDWORD pdwAction)
|
|
{
|
|
HRESULT hr = S_FALSE;
|
|
|
|
if(_pcb)
|
|
hr = _pcb->OnEngineProblem(dwProblem, pdwAction);
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//=---------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=---------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
STDMETHODIMP CInstallEngine::OnComponentProgress(LPCSTR pszID, DWORD dwPhase,
|
|
LPCSTR pszString, LPCSTR pszMsgString, ULONG prog, ULONG max)
|
|
{
|
|
DWORD dwNew;
|
|
|
|
if(dwPhase == INSTALLSTATUS_DOWNLOADING)
|
|
{
|
|
_dwDLOld = prog;
|
|
}
|
|
else if(dwPhase == INSTALLSTATUS_RUNNING)
|
|
{
|
|
_dwInstallOld = prog;
|
|
}
|
|
|
|
if(_pcb)
|
|
_pcb->OnComponentProgress(pszID, dwPhase, pszString, pszMsgString, prog, max);
|
|
|
|
return NOERROR;
|
|
}
|
|
|
|
//=---------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=---------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
STDMETHODIMP CInstallEngine::OnStopComponent(LPCSTR pszID, HRESULT hError,
|
|
DWORD dwPhase, LPCSTR pszString, DWORD dwStatus)
|
|
{
|
|
// adjust remaining
|
|
if(_dwDLRemaining > _dwDLOld)
|
|
_dwDLRemaining -= _dwDLOld;
|
|
else
|
|
_dwDLRemaining = 0;
|
|
|
|
// adjust remaining
|
|
if(_dwInstallRemaining > _dwInstallOld)
|
|
_dwInstallRemaining -= _dwInstallOld;
|
|
else
|
|
_dwInstallRemaining = 0;
|
|
|
|
|
|
wsprintf(szLogBuf, "Timing rates: Download: %d, Install %d\r\n",
|
|
_pDL->GetBytesPerSecond(), _pIns->GetBytesPerSecond());
|
|
WriteToLog(szLogBuf, TRUE);
|
|
|
|
|
|
wsprintf(szLogBuf, "OnStopComponent:\r\n ID: %s\r\n HRESULT: %x (%s)\r\n Phase: %d\r\n Status: %d\r\n",
|
|
pszID, hError, SUCCEEDED(hError) ? STR_OK : STR_FAILED, dwPhase, dwStatus);
|
|
WriteToLog(szLogBuf, TRUE);
|
|
|
|
if(_pcb)
|
|
_pcb->OnStopComponent(pszID, hError, dwPhase, pszString, dwStatus);
|
|
|
|
return NOERROR;
|
|
}
|
|
|
|
//=---------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=---------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
STDMETHODIMP CInstallEngine::OnStopInstall(HRESULT hrError, LPCSTR szError,
|
|
DWORD dwStatus)
|
|
{
|
|
_dwDLRemaining = 0;
|
|
_dwInstallRemaining = 0;
|
|
|
|
wsprintf(szLogBuf, "\r\nOnStopInstall:\r\n HRESULT: %x (%s)\r\n Status: %d\r\n",
|
|
hrError, SUCCEEDED(hrError) ? STR_OK : STR_FAILED, dwStatus);
|
|
WriteToLog(szLogBuf, TRUE);
|
|
|
|
|
|
if(_pcb)
|
|
_pcb->OnStopInstall(hrError, szError, dwStatus);
|
|
|
|
return NOERROR;
|
|
}
|
|
|
|
|
|
//=---------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=---------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
|
|
STDMETHODIMP CInstallEngine::SetIStream(IStream *pstm)
|
|
{
|
|
if(_pStmLog)
|
|
_pStmLog->Release();
|
|
|
|
_pStmLog = pstm;
|
|
if(_pStmLog)
|
|
_pStmLog->AddRef();
|
|
|
|
return NOERROR;
|
|
}
|
|
|
|
//=---------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=---------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
STDMETHODIMP CInstallEngine::GetDisplayName(LPCSTR pszComponentID, LPSTR *ppszName)
|
|
{
|
|
HRESULT hr = E_INVALIDARG;
|
|
char szTitle[MAX_DISPLAYNAME_LENGTH];
|
|
|
|
if(!ppszName)
|
|
return E_POINTER;
|
|
|
|
*ppszName = 0;
|
|
|
|
ICifComponent *pComp = NULL;
|
|
|
|
if(pszComponentID)
|
|
{
|
|
if(SUCCEEDED(_pCif->FindComponent(pszComponentID, &pComp)))
|
|
{
|
|
pComp->GetDescription(szTitle, sizeof(szTitle));
|
|
*ppszName = COPYANSISTR(szTitle);
|
|
if(!(*ppszName))
|
|
hr = E_OUTOFMEMORY;
|
|
else
|
|
hr = NOERROR;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
_pCif->GetDescription(szTitle, sizeof(szTitle));
|
|
*ppszName = COPYANSISTR(szTitle);
|
|
if(!(*ppszName))
|
|
hr = E_OUTOFMEMORY;
|
|
else
|
|
hr = NOERROR;
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
//************** IInstallEngineTiming **********************
|
|
|
|
//=---------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=---------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
STDMETHODIMP CInstallEngine::GetRates(DWORD *pdwDownload, DWORD *pdwInstall)
|
|
{
|
|
*pdwDownload = _pDL->GetBytesPerSecond();
|
|
*pdwInstall = _pIns->GetBytesPerSecond();
|
|
return NOERROR;
|
|
}
|
|
|
|
STDMETHODIMP CInstallEngine::GetInstallProgress(INSTALLPROGRESS *pinsprog)
|
|
{
|
|
if(!pinsprog)
|
|
return E_POINTER;
|
|
|
|
DWORD dwTemp;
|
|
|
|
pinsprog->dwDownloadKBRemaining = _dwDLRemaining - _dwDLOld;
|
|
pinsprog->dwInstallKBRemaining = _dwInstallRemaining - _dwInstallOld;
|
|
|
|
dwTemp = _pDL->GetBytesPerSecond();
|
|
if(dwTemp == 0)
|
|
pinsprog->dwDownloadSecsRemaining = 0xffffffff;
|
|
else
|
|
pinsprog->dwDownloadSecsRemaining = (pinsprog->dwDownloadKBRemaining << 10)/dwTemp;
|
|
|
|
dwTemp = _pIns->GetBytesPerSecond();
|
|
if(dwTemp == 0)
|
|
pinsprog->dwInstallSecsRemaining = 0xffffffff;
|
|
else
|
|
pinsprog->dwInstallSecsRemaining = (pinsprog->dwInstallKBRemaining << 10)/dwTemp;
|
|
|
|
return NOERROR;
|
|
}
|
|
|
|
|
|
HRESULT CInstallEngine::CheckForContinue()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
// Need to check Abort before AND after check for pause...
|
|
if(_pCif->CanCancel() && (WaitForSingleObject(_hAbort, 0) == WAIT_OBJECT_0))
|
|
{
|
|
hr = E_ABORT;
|
|
}
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
WaitForEvent(_hContinue, NULL);
|
|
}
|
|
|
|
if(_pCif->CanCancel() && (WaitForSingleObject(_hAbort, 0) == WAIT_OBJECT_0))
|
|
{
|
|
hr = E_ABORT;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
#define STEPPINGMODE_NO "n"
|
|
|
|
void CInstallEngine::WriteToLog(char *sz, BOOL pause)
|
|
{
|
|
ULONG foo;
|
|
UINT ret;
|
|
HKEY hKey;
|
|
|
|
if(_fSteppingMode && pause)
|
|
{
|
|
ret = MessageBox(_hwndForUI, sz, "Stepping Mode Message", MB_OKCANCEL | MB_ICONINFORMATION);
|
|
if(ret == IDCANCEL)
|
|
{
|
|
// turn off stepping mode
|
|
_fSteppingMode = FALSE;
|
|
// Whack the key
|
|
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, ACTIVESETUP_KEY,0,
|
|
KEY_WRITE, &hKey) == ERROR_SUCCESS)
|
|
{
|
|
// I don't check for failure of delete - what would I do anyways?
|
|
RegSetValueEx(hKey, STEPPING_VALUE, 0, REG_SZ,
|
|
(BYTE *) STEPPINGMODE_NO, lstrlen(STEPPINGMODE_NO) + 1);
|
|
RegCloseKey(hKey);
|
|
}
|
|
}
|
|
}
|
|
|
|
if(_pStmLog)
|
|
_pStmLog->Write(sz, lstrlen(sz), &foo);
|
|
}
|
|
|
|
BOOL CInstallEngine::_IsValidBaseUrl(LPCSTR pszUrl)
|
|
{
|
|
BOOL bValid = TRUE;
|
|
|
|
if(!pszUrl)
|
|
bValid = FALSE;
|
|
|
|
return bValid;
|
|
}
|
|
|