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.
2690 lines
81 KiB
2690 lines
81 KiB
#include "inspch.h"
|
|
#include "inseng.h"
|
|
#include "insobj.h"
|
|
#include "util2.h"
|
|
|
|
|
|
#define MAX_VALUE_LEN 256
|
|
#define MAX_SMALL_BUF 64
|
|
#define NO_ENTRY ""
|
|
|
|
#define UNINSTALL_BRANCH "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall"
|
|
|
|
char g_pBuffer[BUFFERSIZE];
|
|
|
|
#define NUM_RETRIES 2
|
|
|
|
|
|
HINSTANCE CCifComponent::_hDetLib = NULL;
|
|
char CCifComponent::_szDetDllName[] = "";
|
|
|
|
const char c_gszSRLiteOffset[] = "patch/";
|
|
char gszIsPatchable[] = "IsPatchable";
|
|
|
|
|
|
//=--------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=--------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
|
|
CCifComponent::CCifComponent(LPCSTR pszCompID, CCifFile *pCif) : CCifEntry(pszCompID, pCif)
|
|
{
|
|
_dwPlatform = 0xffffffff;
|
|
_uInstallStatus = 0xffffffff;
|
|
_uInstallCount = 0;
|
|
_fDependenciesQueued = FALSE;
|
|
_fUseSRLite = FALSE;
|
|
_fBeforeInstall = TRUE;
|
|
SetDownloadDir("");
|
|
}
|
|
|
|
//=--------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=--------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
CCifComponent::~CCifComponent()
|
|
{
|
|
if(_hDetLib)
|
|
{
|
|
FreeLibrary(_hDetLib);
|
|
_hDetLib = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
STDMETHODIMP CCifComponent::GetID(LPSTR pszID, DWORD dwSize)
|
|
{
|
|
lstrcpyn(pszID, _szID, dwSize);
|
|
return NOERROR;
|
|
}
|
|
|
|
STDMETHODIMP CCifComponent::GetGUID(LPSTR pszGUID, DWORD dwSize)
|
|
{
|
|
return(GetPrivateProfileString(_szID, GUID_KEY, "", pszGUID, dwSize, _pCif->GetCifPath()) ? NOERROR : E_FAIL);
|
|
}
|
|
|
|
STDMETHODIMP CCifComponent::GetDescription(LPSTR pszDesc, DWORD dwSize)
|
|
{
|
|
return(MyTranslateString(_pCif->GetCifPath(), _szID, DISPLAYNAME_KEY, pszDesc, dwSize));
|
|
}
|
|
|
|
STDMETHODIMP CCifComponent::GetDetails(LPSTR pszDetails, DWORD dwSize)
|
|
{
|
|
return(MyTranslateString(_pCif->GetCifPath(), _szID, DETAILS_KEY, pszDetails, dwSize));
|
|
}
|
|
|
|
STDMETHODIMP CCifComponent::GetUrl(UINT uUrlNum, LPSTR pszUrl, DWORD dwSize, LPDWORD pdwUrlFlags)
|
|
{
|
|
char szKey[16];
|
|
char szBuf[MAX_VALUE_LEN];
|
|
HRESULT hr = E_FAIL;
|
|
|
|
// in cif, these things start at 1. we want to start at 0 when handing them out
|
|
uUrlNum++;
|
|
|
|
// Build up the key
|
|
wsprintf(szKey, "%s%lu", URL_KEY, uUrlNum);
|
|
GetPrivateProfileString(_szID, szKey, NO_ENTRY, szBuf, sizeof(szBuf), _pCif->GetCifPath());
|
|
|
|
// See if there is any such entry
|
|
if(lstrcmp(szBuf, NO_ENTRY) != 0)
|
|
{
|
|
// snatch the url name
|
|
if(GetStringField(szBuf, 0, pszUrl, dwSize) != 0)
|
|
{
|
|
// This url looks ok
|
|
hr = NOERROR;
|
|
|
|
*pdwUrlFlags = GetIntField(szBuf, 1, URLF_DEFAULT);
|
|
}
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CCifComponent::GetFileExtractList(UINT uUrlNum, LPSTR pszExtract, DWORD dwSize)
|
|
{
|
|
char szKey[16];
|
|
char szBuf[MAX_VALUE_LEN];
|
|
HRESULT hr = E_FAIL;
|
|
|
|
uUrlNum++;
|
|
|
|
// Build up the key
|
|
wsprintf(szKey, "%s%lu", URL_KEY, uUrlNum);
|
|
GetPrivateProfileString(_szID, szKey, NO_ENTRY, szBuf, sizeof(szBuf), _pCif->GetCifPath());
|
|
|
|
// See if there is any such entry
|
|
if(lstrcmp(szBuf, NO_ENTRY) != 0)
|
|
{
|
|
// snatch the extract list
|
|
if(GetStringField(szBuf, 2, pszExtract, dwSize))
|
|
hr = NOERROR;
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CCifComponent::GetUrlCheckRange(UINT uUrlNum, LPDWORD pdwMin, LPDWORD pdwMax)
|
|
{
|
|
char szKey[16];
|
|
char szBuf[MAX_VALUE_LEN];
|
|
HRESULT hr = E_FAIL;
|
|
|
|
uUrlNum++;
|
|
*pdwMin = *pdwMax = 0;
|
|
|
|
// Build up the key
|
|
wsprintf(szKey, "%s%lu", URLSIZE_KEY, uUrlNum);
|
|
GetPrivateProfileString(_szID, szKey, NO_ENTRY, szBuf, sizeof(szBuf), _pCif->GetCifPath());
|
|
|
|
// See if there is any such entry
|
|
if(lstrcmp(szBuf, NO_ENTRY) != 0)
|
|
{
|
|
// snatch the extract list
|
|
*pdwMin = GetIntField(szBuf, 0, 0);
|
|
*pdwMax = GetIntField(szBuf, 1, *pdwMin);
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CCifComponent::GetCommand(UINT uCmdNum, LPSTR pszCmd, DWORD dwCmdSize,
|
|
LPSTR pszSwitches, DWORD dwSwitchSize, LPDWORD pdwType)
|
|
{
|
|
char szKey[16];
|
|
HRESULT hr = E_FAIL;
|
|
|
|
uCmdNum++;
|
|
// Build up the key
|
|
wsprintf(szKey, "%s%lu", CMD_KEY, uCmdNum);
|
|
GetPrivateProfileString(_szID, szKey, NO_ENTRY, pszCmd, dwCmdSize, _pCif->GetCifPath());
|
|
if(lstrcmp(pszCmd, NO_ENTRY) != 0)
|
|
{
|
|
// Build up the key
|
|
wsprintf(szKey, "%s%d", ARGS_KEY, uCmdNum);
|
|
GetPrivateProfileString(_szID, szKey, NO_ENTRY, pszSwitches, dwSwitchSize, _pCif->GetCifPath());
|
|
// expand #W (or #w) to windows directory
|
|
ExpandString( pszSwitches, dwSwitchSize );
|
|
|
|
// Build up the key
|
|
wsprintf(szKey, "%s%d", TYPE_KEY, uCmdNum);
|
|
|
|
*pdwType = GetPrivateProfileInt(_szID, szKey, CMDF_DEFAULT, _pCif->GetCifPath());
|
|
|
|
hr = NOERROR;
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CCifComponent::GetVersion(LPDWORD pdwVersion, LPDWORD pdwBuild)
|
|
{
|
|
char szBuf[MAX_VALUE_LEN];
|
|
|
|
szBuf[0] = '\0';
|
|
|
|
// Version
|
|
GetPrivateProfileString(_szID, VERSION_KEY, "", szBuf, sizeof(szBuf), _pCif->GetCifPath());
|
|
ConvertVersionStrToDwords(szBuf, pdwVersion, pdwBuild);
|
|
return NOERROR;
|
|
}
|
|
|
|
STDMETHODIMP CCifComponent::GetLocale(LPSTR pszLocale, DWORD dwSize)
|
|
{
|
|
if(FAILED(MyTranslateString(_pCif->GetCifPath(), _szID, LOCALE_KEY, pszLocale, dwSize)))
|
|
lstrcpyn(pszLocale, DEFAULT_LOCALE, dwSize);
|
|
|
|
return NOERROR;
|
|
}
|
|
|
|
STDMETHODIMP CCifComponent::GetUninstallKey(LPSTR pszKey, DWORD dwSize)
|
|
{
|
|
return(GetPrivateProfileString(_szID, UNINSTALLSTRING_KEY, "", pszKey, dwSize, _pCif->GetCifPath()) ? NOERROR : E_FAIL);
|
|
}
|
|
|
|
STDMETHODIMP CCifComponent::GetInstalledSize(LPDWORD pdwWin, LPDWORD pdwApp)
|
|
{
|
|
char szBuf[MAX_VALUE_LEN];
|
|
|
|
if(GetPrivateProfileString(_szID, INSTALLSIZE_KEY, "", szBuf, sizeof(szBuf), _pCif->GetCifPath()))
|
|
{
|
|
*pdwApp = GetIntField(szBuf, 0, 0);
|
|
*pdwWin = GetIntField(szBuf, 1, 0);
|
|
}
|
|
else
|
|
{
|
|
*pdwWin = 0;
|
|
*pdwApp = 2 * GetDownloadSize();
|
|
}
|
|
return NOERROR;
|
|
}
|
|
|
|
STDMETHODIMP_(DWORD) CCifComponent::GetDownloadSize()
|
|
{
|
|
char szBuf[MAX_VALUE_LEN];
|
|
|
|
szBuf[0] = '\0';
|
|
|
|
// Read in size
|
|
GetPrivateProfileString(_szID, SIZE_KEY, "0,0", szBuf, sizeof(szBuf), _pCif->GetCifPath());
|
|
return(GetIntField(szBuf, 0, 0));
|
|
}
|
|
|
|
STDMETHODIMP_(DWORD) CCifComponent::GetExtractSize()
|
|
{
|
|
char szBuf[MAX_VALUE_LEN];
|
|
DWORD dwSize;
|
|
|
|
szBuf[0] = '\0';
|
|
|
|
// Read in size
|
|
GetPrivateProfileString(_szID, SIZE_KEY, "0,0", szBuf, sizeof(szBuf), _pCif->GetCifPath());
|
|
dwSize = GetIntField(szBuf, 1, 2 * GetIntField(szBuf, 0, 0));
|
|
|
|
return dwSize;
|
|
}
|
|
|
|
STDMETHODIMP CCifComponent::GetSuccessKey(LPSTR pszKey, DWORD dwSize)
|
|
{
|
|
return(GetPrivateProfileString(_szID, SUCCESS_KEY, "", pszKey, dwSize, _pCif->GetCifPath()) ? NOERROR : E_FAIL);
|
|
}
|
|
|
|
STDMETHODIMP CCifComponent::GetProgressKeys(LPSTR pszProgress, DWORD dwProgSize, LPSTR pszCancel, DWORD dwCancelSize)
|
|
{
|
|
GetPrivateProfileString(_szID, PROGRESS_KEY, "", pszProgress, dwProgSize, _pCif->GetCifPath());
|
|
GetPrivateProfileString(_szID, MUTEX_KEY, "", pszCancel, dwCancelSize, _pCif->GetCifPath());
|
|
if(*pszProgress != 0 || *pszCancel != 0)
|
|
return NOERROR;
|
|
else
|
|
return E_FAIL;
|
|
}
|
|
|
|
STDMETHODIMP CCifComponent::IsActiveSetupAware()
|
|
{
|
|
return(GetPrivateProfileInt(_szID, ACTSETUPAWARE_KEY, 0, _pCif->GetCifPath()) ? S_OK : S_FALSE);
|
|
}
|
|
|
|
STDMETHODIMP CCifComponent::IsRebootRequired()
|
|
{
|
|
return(GetPrivateProfileInt(_szID, REBOOT_KEY, 0, _pCif->GetCifPath()) ? S_OK : S_FALSE);
|
|
}
|
|
|
|
STDMETHODIMP CCifComponent::RequiresAdminRights()
|
|
{
|
|
return(GetPrivateProfileInt(_szID, ADMIN_KEY, 0, _pCif->GetCifPath()) ? S_OK : S_FALSE);
|
|
}
|
|
|
|
STDMETHODIMP_(DWORD) CCifComponent::GetPriority()
|
|
{
|
|
return(GetPrivateProfileInt(_szID, PRIORITY, 0, _pCif->GetCifPath()));
|
|
}
|
|
|
|
STDMETHODIMP CCifComponent::GetDependency(UINT uDepNum, LPSTR pszID, DWORD dwBuf, char *pchType, LPDWORD pdwVer, LPDWORD pdwBuild)
|
|
{
|
|
char szBuf[MAX_VALUE_LEN];
|
|
char szBuf2[MAX_VALUE_LEN];
|
|
HRESULT hr = E_FAIL;
|
|
DWORD dwLen;
|
|
LPSTR pszTemp;
|
|
DWORD dwV, dwBld;
|
|
|
|
dwV = dwBld = 0xffffffff;
|
|
|
|
if(GetPrivateProfileString(_szID, DEPENDENCY_KEY, NO_ENTRY, szBuf2, sizeof(szBuf2), _pCif->GetCifPath()))
|
|
{
|
|
if(GetStringField(szBuf2, uDepNum, szBuf, sizeof(szBuf)))
|
|
{
|
|
// Do some funky parsing
|
|
dwLen = lstrlen(szBuf);
|
|
*pchType = DEP_INSTALL;
|
|
|
|
pszTemp = FindChar(szBuf, ':');
|
|
if(*pszTemp)
|
|
{
|
|
*pszTemp = 0;
|
|
lstrcpyn(pszID, szBuf, dwBuf);
|
|
pszTemp++;
|
|
*pchType = *pszTemp;
|
|
// see if we have a version
|
|
pszTemp = FindChar(pszTemp, ':');
|
|
if(*pszTemp)
|
|
{
|
|
pszTemp++;
|
|
// wierdness - scan the string, convert . to , for parsing
|
|
LPSTR pszTemp2 = pszTemp;
|
|
while(*pszTemp2 != 0)
|
|
{
|
|
if(*pszTemp2 == '.')
|
|
*pszTemp2 = ',';
|
|
pszTemp2++;
|
|
}
|
|
|
|
ConvertVersionStrToDwords(pszTemp, &dwV, &dwBld);
|
|
|
|
}
|
|
}
|
|
else
|
|
lstrcpyn(pszID, szBuf, dwBuf);
|
|
|
|
if(dwV == 0xffffffff && dwBld == 0xffffffff)
|
|
{
|
|
// get version of dependency from cif
|
|
ICifComponent *pcomp;
|
|
|
|
if(SUCCEEDED(_pCif->FindComponent(pszID, &pcomp)))
|
|
pcomp->GetVersion(&dwV, &dwBld);
|
|
}
|
|
hr = NOERROR;
|
|
}
|
|
|
|
}
|
|
if(pdwVer)
|
|
*pdwVer = dwV;
|
|
|
|
if(pdwBuild)
|
|
*pdwBuild = dwBld;
|
|
|
|
return hr;
|
|
}
|
|
|
|
LPSTR g_pszComp[] = { "Branding.cab",
|
|
"desktop.cab",
|
|
"custom0",
|
|
"custom1",
|
|
"custom2",
|
|
"custom3",
|
|
"custom4",
|
|
"custom5",
|
|
"custom6",
|
|
"custom7",
|
|
"custom8",
|
|
"custom9",
|
|
"CustIcmPro",
|
|
NULL};
|
|
|
|
STDMETHODIMP_(DWORD) CCifComponent::GetPlatform()
|
|
{
|
|
if(_dwPlatform == 0xffffffff)
|
|
{
|
|
char *rszPlatforms[7] = { STR_WIN95, STR_WIN98, STR_NT4, STR_NT5, STR_NT4ALPHA, STR_NT5ALPHA,STR_MILLEN };
|
|
DWORD rdwPlatforms[] = { PLATFORM_WIN95, PLATFORM_WIN98, PLATFORM_NT4, PLATFORM_NT5,
|
|
PLATFORM_NT4ALPHA, PLATFORM_NT5ALPHA, PLATFORM_MILLEN };
|
|
char szBuf[MAX_VALUE_LEN];
|
|
char szPlatBuf[MAX_VALUE_LEN];
|
|
BOOL bFound = FALSE;
|
|
int i = 0;
|
|
|
|
while (!bFound && g_pszComp[i])
|
|
{
|
|
bFound = (lstrcmpi(g_pszComp[i], _szID) == 0);
|
|
i++;
|
|
}
|
|
|
|
_dwPlatform = 0;
|
|
|
|
if(!bFound && GetPrivateProfileString(_szID, PLATFORM_KEY, NO_ENTRY, szBuf, sizeof(szBuf), _pCif->GetCifPath()))
|
|
{
|
|
int j = 0;
|
|
while(GetStringField(szBuf, j++, szPlatBuf, sizeof(szPlatBuf)))
|
|
{
|
|
for(int i = 0; i < 7; i++)
|
|
{
|
|
if(lstrcmpi(szPlatBuf, rszPlatforms[i]) == 0)
|
|
{
|
|
// check if we should add this platform for this component.
|
|
if ((GetCurrentPlatform() != rdwPlatforms[i]) ||
|
|
!DisableComponent())
|
|
_dwPlatform |= rdwPlatforms[i];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
_dwPlatform = PLATFORM_WIN95 | PLATFORM_WIN98 | PLATFORM_NT4 | PLATFORM_NT5 | PLATFORM_NT4ALPHA | PLATFORM_NT5ALPHA | PLATFORM_MILLEN;
|
|
}
|
|
return _dwPlatform;
|
|
}
|
|
|
|
STDMETHODIMP_(BOOL) CCifComponent::DisableComponent()
|
|
{
|
|
BOOL bDisableComp = FALSE;
|
|
BOOL bGuidMatch = FALSE;
|
|
HKEY hKey;
|
|
DWORD dwIndex = 0;
|
|
CHAR szGUIDComp[MAX_VALUE_LEN];
|
|
CHAR szGUID[MAX_VALUE_LEN];
|
|
DWORD dwGUIDSize = sizeof(szGUID);
|
|
CHAR szData[MAX_VALUE_LEN];
|
|
DWORD dwDataSize = sizeof(szData);
|
|
LPSTR pTmp;
|
|
DWORD dwVersion , dwBuild;
|
|
DWORD dwInstallVer, dwInstallBuild;
|
|
|
|
if(RegOpenKeyExA(HKEY_LOCAL_MACHINE, COMPONENTBLOCK_KEY, 0, KEY_READ, &hKey) == ERROR_SUCCESS)
|
|
{
|
|
while (!bDisableComp &&
|
|
(RegEnumValue(hKey, dwIndex, szGUID, &dwGUIDSize, NULL, NULL,
|
|
(LPBYTE)szData, &dwDataSize) == ERROR_SUCCESS) )
|
|
{
|
|
GetGUID(szGUIDComp, sizeof(szGUIDComp));
|
|
pTmp = ANSIStrChr( szGUID, '*' );
|
|
if (pTmp)
|
|
{
|
|
// If there is a * assume it is at the end
|
|
*pTmp = '\0';
|
|
szGUIDComp[lstrlen(szGUID)] = '\0';
|
|
}
|
|
bGuidMatch = (lstrcmpi(szGUID, szGUIDComp) == 0);
|
|
// Did the Guids match?
|
|
if (bGuidMatch)
|
|
{
|
|
// now see if we have version info.
|
|
if (dwDataSize == 0)
|
|
bDisableComp = TRUE;
|
|
else
|
|
{
|
|
// Convert the versin number for the registry
|
|
ConvertVersionStrToDwords(szData, &dwVersion, &dwBuild);
|
|
if (dwVersion == 0)
|
|
bDisableComp = TRUE;
|
|
else
|
|
{
|
|
// Get the versin we would install.
|
|
GetVersion(&dwInstallVer, &dwInstallBuild);
|
|
// If the version we would install is equal or less, disable the component.
|
|
if ((dwInstallVer < dwVersion) ||
|
|
((dwInstallVer == dwVersion) && (dwInstallBuild <= dwBuild)) )
|
|
bDisableComp = TRUE;
|
|
}
|
|
}
|
|
}
|
|
dwGUIDSize = sizeof(szGUID);
|
|
dwDataSize = sizeof(szData);
|
|
dwIndex++;
|
|
}
|
|
RegCloseKey(hKey);
|
|
}
|
|
return bDisableComp;
|
|
}
|
|
|
|
STDMETHODIMP CCifComponent::GetMode(UINT uModeNum, LPSTR pszMode, DWORD dwSize)
|
|
{
|
|
char szBuf[MAX_VALUE_LEN];
|
|
|
|
if(FAILED(MyTranslateString(_pCif->GetCifPath(), _szID, MODES_KEY, szBuf, sizeof(szBuf))))
|
|
return E_FAIL;
|
|
return(GetStringField(szBuf, uModeNum, pszMode, dwSize) ? NOERROR : E_FAIL);
|
|
|
|
}
|
|
|
|
STDMETHODIMP CCifComponent::GetGroup(LPSTR pszID, DWORD dwSize)
|
|
{
|
|
return(GetPrivateProfileString(_szID, GROUP_KEY, "", pszID, dwSize, _pCif->GetCifPath()) ? NOERROR : E_FAIL);
|
|
}
|
|
|
|
STDMETHODIMP CCifComponent::IsUIVisible()
|
|
{
|
|
return(GetPrivateProfileInt(_szID, UIVISIBLE_KEY, 1, _pCif->GetCifPath()) ? S_OK : S_FALSE);
|
|
}
|
|
|
|
|
|
STDMETHODIMP CCifComponent::GetPatchID(LPSTR pszID, DWORD dwSize)
|
|
{
|
|
return(GetPrivateProfileString(_szID, PATCHID_KEY, "", pszID, dwSize, _pCif->GetCifPath()) ? NOERROR : E_FAIL);
|
|
}
|
|
|
|
STDMETHODIMP CCifComponent::GetTreatAsOneComponents(UINT uNum, LPSTR pszID, DWORD dwBuf)
|
|
{
|
|
char szBuf[MAX_VALUE_LEN];
|
|
|
|
szBuf[0] = '\0';
|
|
|
|
GetPrivateProfileString(_szID, TREATAS_KEY, "", szBuf, sizeof(szBuf), _pCif->GetCifPath());
|
|
return(GetStringField(szBuf, uNum, pszID, dwBuf) ? NOERROR : E_FAIL);
|
|
}
|
|
|
|
STDMETHODIMP CCifComponent::GetCustomData(LPSTR pszKey, LPSTR pszData, DWORD dwSize)
|
|
{
|
|
char szNewKey[MAX_VALUE_LEN];
|
|
|
|
wsprintf(szNewKey, "_%s", pszKey);
|
|
|
|
return(MyTranslateString(_pCif->GetCifPath(), _szID, szNewKey, pszData, dwSize));
|
|
}
|
|
|
|
|
|
STDMETHODIMP_(DWORD) CCifComponent::IsComponentInstalled()
|
|
{
|
|
CHAR szCifBuf[512];
|
|
CHAR szCompBuf[512];
|
|
CHAR szGUID[MAX_VALUE_LEN];
|
|
CHAR szLocale[8];
|
|
HKEY hComponentKey = NULL;
|
|
DETECTION_STRUCT Det;
|
|
|
|
DWORD dwCifVer, dwCifBuild, dwInstalledVer, dwInstalledBuild;
|
|
DWORD dwUnused, dwType, dwIsInstalled;
|
|
BOOL bVersionFound = FALSE;
|
|
|
|
if(_uInstallStatus != ICI_NOTINITIALIZED)
|
|
return _uInstallStatus;
|
|
|
|
_uInstallStatus = ICI_NOTINSTALLED;
|
|
|
|
// use detection dll first if it is available
|
|
if ( SUCCEEDED(GetDetVersion(szCifBuf, sizeof(szCifBuf), szCompBuf, sizeof(szCompBuf))))
|
|
{
|
|
GetVersion(&dwCifVer, &dwCifBuild);
|
|
Det.dwSize = sizeof(DETECTION_STRUCT);
|
|
Det.pdwInstalledVer = &dwInstalledVer;
|
|
Det.pdwInstalledBuild = &dwInstalledBuild;
|
|
GetLocale(szLocale, sizeof(szLocale));
|
|
Det.pszLocale = szLocale;
|
|
GetGUID(szGUID, sizeof(szGUID));
|
|
Det.pszGUID = szGUID;
|
|
Det.dwAskVer = dwCifVer;
|
|
Det.dwAskBuild = dwCifBuild;
|
|
Det.pCifFile = (ICifFile *) _pCif;
|
|
Det.pCifComp = (ICifComponent *) this;
|
|
if (SUCCEEDED(_GetDetVerResult(szCifBuf, szCompBuf, &Det, &_uInstallStatus)))
|
|
{
|
|
// only wizard want to know this status, if the newer version is installed, means Installed.
|
|
if (_uInstallStatus == ICI_OLDVERSIONAVAILABLE)
|
|
_uInstallStatus = ICI_INSTALLED;
|
|
return _uInstallStatus;
|
|
}
|
|
}
|
|
|
|
// Build GUID Key
|
|
lstrcpy(szCompBuf, COMPONENT_KEY);
|
|
lstrcat(szCompBuf, "\\");
|
|
GetGUID(szCifBuf, sizeof(szCifBuf));
|
|
lstrcat(szCompBuf, szCifBuf);
|
|
|
|
if(RegOpenKeyExA(HKEY_LOCAL_MACHINE, szCompBuf, 0, KEY_READ, &hComponentKey) == ERROR_SUCCESS)
|
|
{
|
|
// first check for the IsInstalled valuename
|
|
// if the valuename is there AND equals zero, we say not installed.
|
|
// otherwise continue.
|
|
// NOTE: We default to ISINSTALLED_YES if valuename not present to be Back-compatible
|
|
// with when we didn't write this valuename at all.....
|
|
|
|
dwUnused = sizeof(dwIsInstalled);
|
|
if(RegQueryValueEx(hComponentKey, ISINSTALLED_KEY, 0, NULL, (LPBYTE) (&dwIsInstalled), &dwUnused) != ERROR_SUCCESS)
|
|
dwIsInstalled = ISINSTALLED_YES;
|
|
|
|
if(dwIsInstalled == ISINSTALLED_YES)
|
|
{
|
|
|
|
// next check for a locale match (no locale entry use default)
|
|
dwUnused = sizeof(szCompBuf);
|
|
if(RegQueryValueEx(hComponentKey, LOCALE_KEY, 0, NULL, (LPBYTE) szCompBuf, &dwUnused) != ERROR_SUCCESS)
|
|
lstrcpy(szCompBuf, DEFAULT_LOCALE);
|
|
|
|
GetLocale(szCifBuf, sizeof(szCifBuf));
|
|
|
|
if(_fBeforeInstall || (CompareLocales(szCompBuf, szCifBuf) == 0))
|
|
{
|
|
// locales match so go check the version
|
|
|
|
// first check for updated version key
|
|
dwUnused = sizeof(szCompBuf);
|
|
bVersionFound = (RegQueryValueEx(hComponentKey, QFE_VERSION_KEY,
|
|
0, &dwType, (LPBYTE) szCompBuf, &dwUnused) == ERROR_SUCCESS);
|
|
|
|
// if QFEVersion doesn't exist, look for version
|
|
if(!bVersionFound)
|
|
{
|
|
dwUnused = sizeof(szCompBuf);
|
|
bVersionFound = (RegQueryValueEx(hComponentKey, VERSION_KEY,
|
|
0, &dwType, (LPBYTE) szCompBuf, &dwUnused) == ERROR_SUCCESS);
|
|
}
|
|
|
|
// figure out if we have REG_STR
|
|
if(bVersionFound)
|
|
{
|
|
// if we have a string convert to ver, if we have binary directly copy into version struct
|
|
if(dwType == REG_SZ)
|
|
{
|
|
ConvertVersionStrToDwords(szCompBuf, &dwInstalledVer, &dwInstalledBuild);
|
|
|
|
GetVersion(&dwCifVer, &dwCifBuild);
|
|
|
|
if( (dwInstalledVer > dwCifVer) ||
|
|
((dwInstalledVer == dwCifVer) && (dwInstalledBuild >= dwCifBuild)) )
|
|
{
|
|
_uInstallStatus = ICI_INSTALLED;
|
|
}
|
|
else
|
|
{
|
|
_uInstallStatus = ICI_NEWVERSIONAVAILABLE;
|
|
}
|
|
}
|
|
else
|
|
_uInstallStatus = ICI_NEWVERSIONAVAILABLE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if(hComponentKey)
|
|
RegCloseKey(hComponentKey);
|
|
|
|
// We think its installed, now check
|
|
if(_uInstallStatus != ICI_NOTINSTALLED)
|
|
{
|
|
// if there is an uninstall key to check do it
|
|
if(SUCCEEDED(GetUninstallKey(szCompBuf, sizeof(szCompBuf))))
|
|
{
|
|
|
|
if(!UninstallKeyExists(szCompBuf))
|
|
{
|
|
_uInstallStatus = ICI_NOTINSTALLED;
|
|
}
|
|
else
|
|
{
|
|
// if there is a success key to check do it
|
|
if(SUCCEEDED(GetSuccessKey(szCompBuf, sizeof(szCompBuf))))
|
|
{
|
|
if(!SuccessCheck(szCompBuf))
|
|
{
|
|
_uInstallStatus = ICI_NOTINSTALLED;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return _uInstallStatus;
|
|
}
|
|
|
|
|
|
|
|
STDMETHODIMP CCifComponent::IsComponentDownloaded()
|
|
{
|
|
if(GetActualDownloadSize() == 0)
|
|
return S_OK;
|
|
else
|
|
return S_FALSE;
|
|
}
|
|
|
|
STDMETHODIMP_(DWORD) CCifComponent::IsThisVersionInstalled(DWORD dwAskVer, DWORD dwAskBld, LPDWORD pdwVersion, LPDWORD pdwBuild)
|
|
{
|
|
CHAR szCifBuf[512];
|
|
CHAR szCompBuf[512];
|
|
CHAR szLocale[8];
|
|
CHAR szGUID[MAX_VALUE_LEN];
|
|
DETECTION_STRUCT Det;
|
|
HKEY hComponentKey = NULL;
|
|
UINT uStatus = ICI_NOTINSTALLED;
|
|
|
|
*pdwVersion = 0;
|
|
*pdwBuild = 0;
|
|
|
|
// use detection dll first if it is available
|
|
if ( SUCCEEDED(GetDetVersion(szCifBuf, sizeof(szCifBuf), szCompBuf, sizeof(szCompBuf))))
|
|
{
|
|
Det.dwSize = sizeof(DETECTION_STRUCT);
|
|
Det.pdwInstalledVer = pdwVersion;
|
|
Det.pdwInstalledBuild = pdwBuild;
|
|
GetLocale(szLocale, sizeof(szLocale));
|
|
Det.pszLocale = szLocale;
|
|
GetGUID(szGUID, sizeof(szGUID));
|
|
Det.pszGUID = szGUID;
|
|
Det.dwAskVer = dwAskVer;
|
|
Det.dwAskBuild = dwAskBld;
|
|
Det.pCifFile = (ICifFile *) _pCif;
|
|
Det.pCifComp = (ICifComponent *) this;
|
|
if (SUCCEEDED(_GetDetVerResult(szCifBuf, szCompBuf, &Det, &uStatus)))
|
|
{
|
|
return uStatus;
|
|
}
|
|
}
|
|
|
|
if(IsComponentInstalled() == ICI_NOTINSTALLED)
|
|
return uStatus;
|
|
|
|
DWORD dwUnused, dwType;
|
|
BOOL bVersionFound = FALSE;
|
|
|
|
// Build GUID Key
|
|
lstrcpy(szCompBuf, COMPONENT_KEY);
|
|
lstrcat(szCompBuf, "\\");
|
|
GetGUID(szCifBuf, sizeof(szCifBuf));
|
|
lstrcat(szCompBuf, szCifBuf);
|
|
|
|
if(RegOpenKeyExA(HKEY_LOCAL_MACHINE, szCompBuf, 0, KEY_READ, &hComponentKey) == ERROR_SUCCESS)
|
|
{
|
|
// first check for updated version key
|
|
dwUnused = sizeof(szCompBuf);
|
|
bVersionFound = (RegQueryValueEx(hComponentKey, QFE_VERSION_KEY,
|
|
0, &dwType, (LPBYTE) szCompBuf, &dwUnused) == ERROR_SUCCESS);
|
|
|
|
// if QFEVersion doesn't exist, look for version
|
|
if(!bVersionFound)
|
|
{
|
|
dwUnused = sizeof(szCompBuf);
|
|
bVersionFound = (RegQueryValueEx(hComponentKey, VERSION_KEY,
|
|
0, &dwType, (LPBYTE) szCompBuf, &dwUnused) == ERROR_SUCCESS);
|
|
}
|
|
|
|
//figure out if we have REG_STR
|
|
if(bVersionFound)
|
|
{
|
|
// if we have a string convert to ver, if we have binary directly copy into version struct
|
|
if(dwType == REG_SZ)
|
|
{
|
|
ConvertVersionStrToDwords(szCompBuf, pdwVersion, pdwBuild);
|
|
|
|
if((*pdwVersion == dwAskVer) && (*pdwBuild == dwAskBld) )
|
|
{
|
|
uStatus = ICI_INSTALLED;
|
|
}
|
|
else if ((*pdwVersion > dwAskVer) ||
|
|
(*pdwVersion == dwAskVer) && (*pdwBuild > dwAskBld) )
|
|
{
|
|
uStatus = ICI_OLDVERSIONAVAILABLE;
|
|
}
|
|
else
|
|
{
|
|
uStatus = ICI_NEWVERSIONAVAILABLE;
|
|
}
|
|
}
|
|
else
|
|
uStatus = ICI_NEWVERSIONAVAILABLE;
|
|
}
|
|
RegCloseKey(hComponentKey);
|
|
}
|
|
return uStatus;
|
|
}
|
|
|
|
STDMETHODIMP_(DWORD) CCifComponent::GetInstallQueueState()
|
|
{
|
|
if(_uInstallCount)
|
|
return SETACTION_INSTALL;
|
|
else
|
|
return SETACTION_NONE;
|
|
}
|
|
|
|
STDMETHODIMP CCifComponent::SetInstallQueueState(DWORD dwState)
|
|
{
|
|
HRESULT hr = NOERROR;
|
|
DWORD uDependencyAction;
|
|
char szCompBuf[MAX_ID_LENGTH];
|
|
char chType;
|
|
ICifComponent *pcomp;
|
|
BOOL fProcessDependencies = TRUE;
|
|
|
|
// check to see if we allow install on this platform
|
|
if((dwState != SETACTION_NONE) && (dwState != SETACTION_DEPENDENCYNONE) &&
|
|
!_pCif->GetInstallEngine()->AllowCrossPlatform())
|
|
{
|
|
if(!(GetPlatform() & GetCurrentPlatform()))
|
|
return S_FALSE;
|
|
}
|
|
|
|
switch(dwState)
|
|
{
|
|
case SETACTION_INSTALL:
|
|
// check if it was already on. If so, don't process dependencies
|
|
if(_uInstallCount & 0x80000000)
|
|
fProcessDependencies = FALSE;
|
|
|
|
_uInstallCount |= 0x80000000;
|
|
uDependencyAction = SETACTION_DEPENDENCYINSTALL;
|
|
break;
|
|
case SETACTION_DEPENDENCYINSTALL:
|
|
_uInstallCount++;
|
|
uDependencyAction = SETACTION_DEPENDENCYINSTALL;
|
|
break;
|
|
case SETACTION_NONE:
|
|
// check if it was not on to begin with. If not, don't process dependencies
|
|
if(!(_uInstallCount & 0x80000000))
|
|
fProcessDependencies = FALSE;
|
|
|
|
_uInstallCount &= 0x7fffffff;
|
|
uDependencyAction = SETACTION_DEPENDENCYNONE;
|
|
break;
|
|
case SETACTION_DEPENDENCYNONE:
|
|
// if our depdency refcount is greater than zero, decrement it.
|
|
// this allows us to unconditionally call this when an item is "unqueued"
|
|
if(_uInstallCount & 0x7fffffff) _uInstallCount--;
|
|
uDependencyAction = SETACTION_DEPENDENCYNONE;
|
|
break;
|
|
default:
|
|
hr = E_INVALIDARG;
|
|
break;
|
|
}
|
|
|
|
// now set each dependency, if needed
|
|
if(SUCCEEDED(hr) && fProcessDependencies)
|
|
{
|
|
if(!_fDependenciesQueued)
|
|
{
|
|
_fDependenciesQueued = TRUE;
|
|
DWORD dwNeedVer, dwNeedBuild, dwInsVer, dwInsBuild;
|
|
for(int i = 0; SUCCEEDED(GetDependency(i, szCompBuf, sizeof(szCompBuf), &chType, &dwNeedVer, &dwNeedBuild)); i++)
|
|
{
|
|
if(chType == DEP_INSTALL || chType == DEP_BUDDY)
|
|
{
|
|
if(SUCCEEDED(_pCif->FindComponent(szCompBuf, &pcomp)))
|
|
{
|
|
// queue for install if
|
|
// 1. Not installed
|
|
// 2. Not a good enough version
|
|
// 3. FORCEDEPENDIECIES is set
|
|
UINT uStatus = pcomp->IsThisVersionInstalled(dwNeedVer, dwNeedBuild, &dwInsVer, &dwInsBuild);
|
|
if( (uStatus == ICI_NOTINSTALLED) ||
|
|
(uStatus == ICI_NEWVERSIONAVAILABLE) ||
|
|
(_pCif->GetInstallEngine()->ForceDependencies()) )
|
|
pcomp->SetInstallQueueState(uDependencyAction);
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
_fDependenciesQueued = FALSE;
|
|
}
|
|
}
|
|
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
STDMETHODIMP_(DWORD) CCifComponent::GetActualDownloadSize()
|
|
{
|
|
char szCompBuf[MAX_PATH];
|
|
LPSTR pszFilename = NULL;
|
|
LPSTR pszPathEnd = NULL;
|
|
DWORD dwUrlSize, dwFlags;
|
|
DWORD dwTotalSize = 0;
|
|
BOOL alldownloaded = TRUE;
|
|
|
|
if (_fUseSRLite)
|
|
{
|
|
// Let the patching engine determine the correct value
|
|
dwTotalSize = 0;
|
|
}
|
|
else
|
|
{
|
|
|
|
if(_CompareDownloadInfo())
|
|
{
|
|
// so our versions match correctly, check each file
|
|
for(UINT i = 0; SUCCEEDED(GetUrl(i, szCompBuf, sizeof(szCompBuf), &dwFlags)); i++)
|
|
{
|
|
pszFilename = ParseURLA(szCompBuf);
|
|
|
|
if(_FileIsDownloaded(pszFilename, i, &dwUrlSize))
|
|
dwTotalSize += dwUrlSize;
|
|
else
|
|
alldownloaded = FALSE;
|
|
}
|
|
}
|
|
else
|
|
alldownloaded = FALSE;
|
|
|
|
if(alldownloaded)
|
|
dwTotalSize = 0;
|
|
else
|
|
dwTotalSize = GetDownloadSize() - (dwTotalSize >> 10);
|
|
}
|
|
|
|
return dwTotalSize;
|
|
}
|
|
|
|
HRESULT CCifComponent::OnProgress(ULONG uProgSoFar, LPCSTR pszStatus)
|
|
{
|
|
_uIndivProgress = uProgSoFar;
|
|
if(_uTotalProgress + _uIndivProgress > _uTotalGoal)
|
|
_uIndivProgress = _uTotalGoal - _uTotalProgress;
|
|
|
|
_pCif->GetInstallEngine()->OnComponentProgress(_szID, _uPhase, _szDesc,
|
|
pszStatus, _uTotalProgress + _uIndivProgress, _uTotalGoal);
|
|
|
|
return NOERROR;
|
|
}
|
|
|
|
|
|
|
|
STDMETHODIMP_(DWORD) CCifComponent::GetCurrentPriority()
|
|
{
|
|
if(_uPriority == 0xffffffff)
|
|
{
|
|
char szID[MAX_ID_LENGTH];
|
|
ICifGroup *pgrp;
|
|
|
|
_uPriority = 0;
|
|
GetGroup(szID, sizeof(szID));
|
|
|
|
if(SUCCEEDED(_pCif->FindGroup(szID, &pgrp)))
|
|
{
|
|
_uPriority = pgrp->GetCurrentPriority();
|
|
}
|
|
_uPriority += GetPriority();
|
|
}
|
|
return _uPriority;
|
|
}
|
|
|
|
STDMETHODIMP CCifComponent::SetCurrentPriority(DWORD dwPriority)
|
|
{
|
|
_uPriority = dwPriority;
|
|
|
|
// priorities may have changed need to resort
|
|
_pCif->ReinsertComponent(this);
|
|
return NOERROR;
|
|
}
|
|
|
|
HRESULT CCifComponent::Download()
|
|
{
|
|
char szBuf[INTERNET_MAX_URL_LENGTH];
|
|
HRESULT hr = NOERROR;
|
|
DWORD uType;
|
|
|
|
GetDescription(_szDesc, sizeof(_szDesc));
|
|
// BUGBUG: Download size isn't accurate for SR lite and patching
|
|
_uTotalGoal = GetActualDownloadSize();
|
|
|
|
// Engage SR lite behavior only if we're going to install the component,
|
|
// and the new advpack extension is available.
|
|
DWORD dwOptions = 0;
|
|
BOOL fRetryClassic = TRUE;
|
|
CHAR szCompBuf[MAX_VALUE_LEN];
|
|
CHAR szDir[MAX_PATH];
|
|
LPSTR pszSubDir = NULL;
|
|
CHAR szCanPatch[MAX_VALUE_LEN];
|
|
|
|
lstrcpyn(szDir, _pCif->GetDownloadDir(), sizeof(szDir));
|
|
SetDownloadDir(szDir);
|
|
|
|
if (IsPatchableIEVersion() &&
|
|
SUCCEEDED(_pCif->GetInstallEngine()->GetInstallOptions(&dwOptions)) &&
|
|
(dwOptions & INSTALLOPTIONS_INSTALL) &&
|
|
(dwOptions & INSTALLOPTIONS_DOWNLOAD) &&
|
|
_pCif->GetInstallEngine()->IsAdvpackExtAvailable() &&
|
|
_pCif->GetInstallEngine()->GetPatchDownloader()->IsEnabled() &&
|
|
SUCCEEDED(GetCustomData(gszIsPatchable, szCanPatch, sizeof(szCanPatch))) &&
|
|
lstrcmp(szCanPatch, "1") == 0)
|
|
{
|
|
_fUseSRLite = TRUE;
|
|
// Adjust the download directory
|
|
// The idea here is that the download directory will contain
|
|
// subdirectories which will contain the empty cabs + inf +
|
|
// the downloaded files.
|
|
//
|
|
GetID(szCompBuf, sizeof(szCompBuf));
|
|
|
|
wsprintf(szLogBuf, "Attempting to download empty cabs for %s\r\n", szCompBuf);
|
|
_pCif->GetInstallEngine()->WriteToLog(szLogBuf, FALSE);
|
|
|
|
AddPath(szDir, szCompBuf);
|
|
SetDownloadDir(szDir);
|
|
|
|
if (GetFileAttributes(szDir) == 0xFFFFFFFF)
|
|
CreateDirectory(szDir, NULL);
|
|
}
|
|
|
|
_pCif->GetInstallEngine()->OnStartComponent(_szID, _uTotalGoal, 0 , _szDesc);
|
|
|
|
_MarkDownloadStarted();
|
|
|
|
// check for disk space
|
|
_uPhase = INSTALLSTATUS_INITIALIZING;
|
|
_pCif->GetInstallEngine()->OnComponentProgress(_szID, _uPhase, _szDesc, NULL, 0, 0);
|
|
|
|
if(!IsEnoughSpace(GetDownloadDir(), _uTotalGoal))
|
|
hr = E_FAIL;
|
|
|
|
_uTotalProgress = 0;
|
|
for(int i = 0; SUCCEEDED(hr) && SUCCEEDED(GetUrl(i, szBuf, sizeof(szBuf), &uType)); i++)
|
|
{
|
|
// Change the download loc to point to the special
|
|
// "empty cab" location, so we can download the empty
|
|
// cabs + the INF that will contain instructions for
|
|
// generating the file list for this type of installation.
|
|
//
|
|
// Assume the new download loc to be in the "patch" subdirectory
|
|
// relative to the passed in URL
|
|
//
|
|
// BUGBUG... only handle the case for relative URLs
|
|
if (_fUseSRLite && (uType & URLF_RELATIVEURL) && lstrlen(c_gszSRLiteOffset) + lstrlen(szBuf) < INTERNET_MAX_URL_LENGTH)
|
|
{
|
|
char szBuf2[INTERNET_MAX_URL_LENGTH];
|
|
lstrcpy(szBuf2, c_gszSRLiteOffset);
|
|
lstrcat(szBuf2, szBuf);
|
|
|
|
hr = _DownloadUrl(i, szBuf2, uType);
|
|
|
|
wsprintf(szLogBuf, "Empty cab download of %s returned 0x%lx\r\n", szBuf2, hr);
|
|
_pCif->GetInstallEngine()->WriteToLog(szLogBuf, FALSE);
|
|
}
|
|
else
|
|
{
|
|
wsprintf(szLogBuf, "Initial download attempt will be tried as a full download.\r\n");
|
|
_pCif->GetInstallEngine()->WriteToLog(szLogBuf, FALSE);
|
|
// No need to retry because the first attempt will be the old way...
|
|
fRetryClassic = FALSE;
|
|
|
|
// Restore the download dir to the same state as a normal
|
|
// full download.
|
|
if (_fUseSRLite)
|
|
{
|
|
SetDownloadDir(_pCif->GetDownloadDir());
|
|
|
|
// Ensure we're set to false...just in case there was a problem
|
|
// with obtaining the URL for the SR Lite download.
|
|
_fUseSRLite = FALSE;
|
|
}
|
|
hr = _DownloadUrl(i, szBuf, uType);
|
|
}
|
|
}
|
|
|
|
if (_fUseSRLite && SUCCEEDED(hr))
|
|
{
|
|
// Ok...time for the real action of using advpext.dll to
|
|
// download the needed files.
|
|
hr = _SRLiteDownloadFiles();
|
|
}
|
|
|
|
if (_fUseSRLite && !SUCCEEDED(hr))
|
|
{
|
|
DelNode(szDir, 0);
|
|
// Restore the download dir
|
|
SetDownloadDir(_pCif->GetDownloadDir());
|
|
}
|
|
|
|
if(SUCCEEDED(hr))
|
|
_uPhase = INSTALLSTATUS_DOWNLOADFINISHED;
|
|
else if (_fUseSRLite && fRetryClassic)
|
|
{
|
|
// Fall back to downloading the full cabs.
|
|
_fUseSRLite = FALSE;
|
|
|
|
_pCif->GetInstallEngine()->WriteToLog("Retrying via full download\r\n", FALSE);
|
|
|
|
hr = S_OK;
|
|
// this re-sets the progress for the retry
|
|
_uPhase = INSTALLSTATUS_DOWNLOADING;
|
|
_pCif->GetInstallEngine()->OnComponentProgress(_szID, _uPhase, _szDesc, NULL, 0, 0);
|
|
_uTotalProgress = 0;
|
|
|
|
for(int i = 0; SUCCEEDED(hr) && SUCCEEDED(GetUrl(i, szBuf, sizeof(szBuf), &uType)); i++)
|
|
{
|
|
hr = _DownloadUrl(i, szBuf, uType);
|
|
}
|
|
if(SUCCEEDED(hr))
|
|
_uPhase = INSTALLSTATUS_DOWNLOADFINISHED;
|
|
}
|
|
|
|
_pCif->GetInstallEngine()->OnStopComponent(_szID, hr, _uPhase, _szDesc, 0);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CCifComponent::_DownloadUrl(UINT uUrlNum, LPCSTR pszUrl, UINT uType)
|
|
{
|
|
// call the downloader
|
|
// check the file
|
|
// if good
|
|
// move to download dir
|
|
// else
|
|
// redo
|
|
HRESULT hr;
|
|
char szTempfile[MAX_PATH];
|
|
char szFullUrl[INTERNET_MAX_URL_LENGTH];
|
|
UINT uStartProgress;
|
|
char szDest[MAX_PATH];
|
|
char szTimeStamp[MAX_PATH*2];
|
|
|
|
|
|
_uPhase = INSTALLSTATUS_DOWNLOADING;
|
|
|
|
if(_FileIsDownloaded(ParseURLA(pszUrl), uUrlNum, NULL))
|
|
return NOERROR;
|
|
|
|
|
|
CDownloader *pDL = _pCif->GetInstallEngine()->GetDownloader();
|
|
|
|
|
|
|
|
uStartProgress = _uTotalProgress;
|
|
|
|
|
|
// retry until success
|
|
// save starting progress in case we retry
|
|
hr = E_FAIL;
|
|
for(int i = 1; i <= NUM_RETRIES && FAILED(hr) && (hr != E_ABORT); i++)
|
|
{
|
|
_uTotalProgress = uStartProgress;
|
|
|
|
if(uType & URLF_RELATIVEURL)
|
|
{
|
|
lstrcpyn(szFullUrl, _pCif->GetInstallEngine()->GetBaseUrl(),
|
|
INTERNET_MAX_URL_LENGTH - (lstrlen(pszUrl) + 2));
|
|
lstrcat(szFullUrl, "/");
|
|
lstrcat(szFullUrl, pszUrl);
|
|
}
|
|
else
|
|
lstrcpy(szFullUrl, pszUrl);
|
|
|
|
if(SUCCEEDED(_pCif->GetInstallEngine()->CheckForContinue()))
|
|
{
|
|
DWORD dwFlags = 0;
|
|
|
|
if(_pCif->GetInstallEngine()->UseCache())
|
|
dwFlags |= DOWNLOADFLAGS_USEWRITECACHE;
|
|
|
|
hr = pDL->SetupDownload(szFullUrl, (IMyDownloadCallback *) this, dwFlags, NULL);
|
|
szTempfile[0] = 0;
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
// Log the start time.
|
|
wsprintf(szLogBuf, " Downloading : %s\r\n", szFullUrl);
|
|
_pCif->GetInstallEngine()->WriteToLog(szLogBuf, FALSE);
|
|
GetTimeDateStamp(szTimeStamp);
|
|
wsprintf(szLogBuf, " Start : %s\r\n", szTimeStamp);
|
|
_pCif->GetInstallEngine()->WriteToLog(szLogBuf, FALSE);
|
|
|
|
hr = pDL->DoDownload(szTempfile, sizeof(szTempfile));
|
|
|
|
// Log the stop time.
|
|
GetTimeDateStamp(szTimeStamp);
|
|
wsprintf(szLogBuf, " Stop : %s\r\n", szTimeStamp);
|
|
_pCif->GetInstallEngine()->WriteToLog(szLogBuf, FALSE);
|
|
wsprintf(szLogBuf, " Result: %x (%s)\r\n", hr, SUCCEEDED(hr) ? STR_OK : STR_FAILED);
|
|
_pCif->GetInstallEngine()->WriteToLog(szLogBuf, FALSE);
|
|
}
|
|
}
|
|
else
|
|
hr = E_ABORT;
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
// Check if it is save to download from this URL
|
|
_uPhase = INSTALLSTATUS_CHECKINGTRUST;
|
|
|
|
hr = _pCif->GetInstallEngine()->CheckForContinue();
|
|
|
|
if(SUCCEEDED(hr))
|
|
hr = _CheckForTrust(szFullUrl, szTempfile);
|
|
|
|
if(SUCCEEDED(hr) && (hr == S_FALSE) )
|
|
{
|
|
DWORD dwMin, dwMax;
|
|
DWORD dwFileSize = 0;
|
|
dwFileSize = MyGetFileSize(szTempfile);
|
|
dwFileSize = dwFileSize >> 10;
|
|
/*
|
|
// Open the file
|
|
HANDLE h = CreateFile(szTempfile, GENERIC_READ, 0, NULL,
|
|
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
|
|
if(h != INVALID_HANDLE_VALUE)
|
|
{
|
|
dwFileSize = GetFileSize(h, NULL);
|
|
CloseHandle(h);
|
|
}
|
|
*/
|
|
GetUrlCheckRange(uUrlNum, &dwMin, &dwMax);
|
|
if(dwMin != 0)
|
|
{
|
|
if(dwMin > dwFileSize || dwMax < dwFileSize)
|
|
hr = E_FAIL;
|
|
else
|
|
hr = S_OK;
|
|
}
|
|
}
|
|
|
|
if(SUCCEEDED(hr))
|
|
hr = _pCif->GetInstallEngine()->CheckForContinue();
|
|
|
|
|
|
// so now we downloaded and checked
|
|
// if it is OK, move to download dir
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
lstrcpy(szDest, GetDownloadDir());
|
|
AddPath(szDest, ParseURLA(pszUrl));
|
|
|
|
if(!CopyFile(szTempfile, szDest, FALSE))
|
|
{
|
|
wsprintf(szLogBuf, "CopyFile FAILED, szTempfile=%s, szDest=%s\r\n", szTempfile, szDest);
|
|
_pCif->GetInstallEngine()->WriteToLog(szLogBuf, FALSE);
|
|
hr = E_FAIL;
|
|
}
|
|
|
|
_uTotalProgress += _uIndivProgress;
|
|
}
|
|
|
|
// delete the temp download copy
|
|
if(szTempfile[0] != 0)
|
|
{
|
|
GetParentDir(szTempfile);
|
|
DelNode(szTempfile, 0);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
if(FAILED(hr) && (hr != E_ABORT))
|
|
{
|
|
// we failed
|
|
// if this is last retry, call EngineProblem
|
|
// else just retry
|
|
if(i == NUM_RETRIES)
|
|
{
|
|
HRESULT hEngProb;
|
|
DWORD dwResult = 0;
|
|
|
|
hEngProb = _pCif->GetInstallEngine()->OnEngineProblem(ENGINEPROBLEM_DOWNLOADFAIL, &dwResult);
|
|
if(hEngProb == S_OK)
|
|
{
|
|
if(dwResult == DOWNLOADFAIL_RETRY)
|
|
i = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if(SUCCEEDED(hr))
|
|
_MarkFileDownloadFinished(szDest, uUrlNum, ParseURLA(pszUrl));
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CCifComponent::Install()
|
|
{
|
|
CHAR szCompBuf[MAX_PATH];
|
|
HKEY hKey;
|
|
DWORD dwWin, dwApp;
|
|
HRESULT hr = NOERROR;
|
|
DWORD dwStatus = 0;
|
|
|
|
GetTimeDateStamp(szCompBuf);
|
|
wsprintf(szLogBuf, " Start : %s\r\n", szCompBuf);
|
|
_pCif->GetInstallEngine()->WriteToLog(szLogBuf, FALSE);
|
|
|
|
szCompBuf[0] = 0;
|
|
|
|
_uInstallStatus = ICI_NOTINITIALIZED;
|
|
|
|
GetDescription(_szDesc, sizeof(_szDesc));
|
|
|
|
GetInstalledSize(&dwWin, &dwApp);
|
|
_uTotalGoal = dwWin + dwApp;
|
|
_pCif->GetInstallEngine()->OnStartComponent(_szID, 0, _uTotalGoal, _szDesc);
|
|
|
|
_uPhase = INSTALLSTATUS_DEPENDENCY;
|
|
hr = _CheckForDependencies();
|
|
|
|
// check for disk space here
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
_uPhase = INSTALLSTATUS_INITIALIZING;
|
|
_pCif->GetInstallEngine()->OnComponentProgress(_szID, _uPhase, _szDesc, NULL, 0, 0);
|
|
hr = CreateTempDir(GetDownloadSize(), GetExtractSize(), _pCif->GetInstallEngine()->GetInstallDrive(),
|
|
dwApp, dwWin, szCompBuf, sizeof(szCompBuf), 0);
|
|
}
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
if( IsNT() && (RequiresAdminRights() == S_OK) && !IsNTAdmin(0,NULL))
|
|
{
|
|
hr = E_ACCESSDENIED;
|
|
_pCif->GetInstallEngine()->WriteToLog("Admin Check failed\n", TRUE);
|
|
}
|
|
}
|
|
|
|
_uTotalProgress = 0;
|
|
|
|
// BUGBUG: ie6wzd sets the download directory for non web-based
|
|
// installs at a later time. Make sure it's set here
|
|
// if we weren't successful with installing via SR Lite.
|
|
if (lstrlen(GetDownloadDir()) == 0)
|
|
{
|
|
SetDownloadDir(_pCif->GetDownloadDir());
|
|
}
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
hr = _CopyAllUrls(szCompBuf);
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
// The new PerUser method requires to leave the IsInstalled flag & StubPath as it was
|
|
//_MarkComponentInstallStarted();
|
|
|
|
_pCif->GetInstallEngine()->GetInstaller()->StartClock();
|
|
|
|
hr = _RunAllCommands(szCompBuf, &dwStatus);
|
|
}
|
|
}
|
|
|
|
if(szCompBuf[0] != 0)
|
|
DelNode(szCompBuf, 0);
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
_fBeforeInstall = FALSE;
|
|
// we think it made it, now double check
|
|
if(IsActiveSetupAware() == S_OK)
|
|
{
|
|
if(IsComponentInstalled() != ICI_INSTALLED)
|
|
{
|
|
// we think they made it but they didn't write their key ...
|
|
_pCif->GetInstallEngine()->WriteToLog("Component did not write to InstalledComponent branch\r\n", TRUE);
|
|
hr = E_FAIL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
char szCompBuf[MAX_VALUE_LEN];
|
|
// if there is an uninstall key to check do it
|
|
if(SUCCEEDED(GetUninstallKey(szCompBuf, sizeof(szCompBuf))))
|
|
{
|
|
if(!UninstallKeyExists(szCompBuf))
|
|
{
|
|
_pCif->GetInstallEngine()->WriteToLog("UninstallKey check failed\r\n", TRUE);
|
|
hr = E_FAIL;
|
|
}
|
|
else
|
|
{
|
|
// if there is a success key to check do it
|
|
if(SUCCEEDED(GetSuccessKey(szCompBuf, sizeof(szCompBuf))))
|
|
{
|
|
if(!SuccessCheck(szCompBuf))
|
|
{
|
|
_pCif->GetInstallEngine()->WriteToLog("Success key check failed\r\n", TRUE);
|
|
hr = E_FAIL;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
_pCif->RemoveFromCriticalComponents(this);
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
_MarkAsInstalled();
|
|
|
|
_pCif->MarkCriticalComponents(this);
|
|
|
|
_uPhase = INSTALLSTATUS_FINISHED;
|
|
_pCif->GetInstallEngine()->GetInstaller()->SetBytes((dwWin + dwApp) << 10, TRUE);
|
|
if(IsRebootRequired() == S_OK)
|
|
{
|
|
dwStatus |= STOPINSTALL_REBOOTNEEDED;
|
|
}
|
|
_pCif->GetInstallEngine()->SetStatus(dwStatus);
|
|
}
|
|
_pCif->GetInstallEngine()->GetInstaller()->StopClock();
|
|
_pCif->GetInstallEngine()->OnStopComponent(_szID, hr, _uPhase, _szDesc, dwStatus);
|
|
GetTimeDateStamp(szCompBuf);
|
|
wsprintf(szLogBuf, " Stop : %s\r\n", szCompBuf);
|
|
_pCif->GetInstallEngine()->WriteToLog(szLogBuf, FALSE);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CCifComponent::_RunAllCommands(LPCSTR pszDir, DWORD *pdwStatus)
|
|
{
|
|
char szCmd[MAX_PATH];
|
|
char szArg[MAX_VALUE_LEN];
|
|
char szProg[MAX_VALUE_LEN];
|
|
char szCancel[MAX_VALUE_LEN];
|
|
char szPath[] = "X:\\";
|
|
DWORD dwWinSpace, dwInstallSpace;
|
|
|
|
DWORD dwType;
|
|
HRESULT hr = NOERROR;
|
|
|
|
// Save the widows space and install drive space
|
|
szPath[0] = g_szWindowsDir[0];
|
|
dwWinSpace = GetSpace(szPath);
|
|
if(szPath[0] != _pCif->GetInstallEngine()->GetInstallDrive())
|
|
{
|
|
szPath[0] = _pCif->GetInstallEngine()->GetInstallDrive();
|
|
dwInstallSpace = GetSpace(szPath);
|
|
}
|
|
else
|
|
{
|
|
dwInstallSpace = 0;
|
|
}
|
|
|
|
|
|
|
|
_uTotalProgress = 0;
|
|
_uPhase = INSTALLSTATUS_RUNNING;
|
|
_pCif->GetInstallEngine()->OnComponentProgress(_szID, INSTALLSTATUS_RUNNING,
|
|
_szDesc, NULL, _uTotalProgress, _uTotalGoal);
|
|
|
|
|
|
hr = _pCif->GetInstallEngine()->CheckForContinue();
|
|
|
|
for(UINT i = 0; SUCCEEDED(hr) && SUCCEEDED(GetCommand(i, szCmd, sizeof(szCmd), szArg, sizeof(szArg), &dwType)); i++)
|
|
{
|
|
_uIndivProgress = 0;
|
|
GetProgressKeys(szProg, sizeof(szProg), szCancel, sizeof(szCancel));
|
|
hr = _pCif->GetInstallEngine()->GetInstaller()->DoInstall(pszDir, szCmd, szArg,
|
|
lstrlen(szProg) ? szProg : NULL, lstrlen(szCancel) ? szCancel : NULL,
|
|
dwType, pdwStatus, (IMyDownloadCallback *) this) ;
|
|
_uTotalProgress += _uIndivProgress;
|
|
}
|
|
|
|
_pCif->GetInstallEngine()->OnComponentProgress(_szID, _uPhase, _szDesc, NULL, _uTotalGoal,_uTotalGoal);
|
|
|
|
// figure how much we used, and log it
|
|
szPath[0] = g_szWindowsDir[0];
|
|
dwWinSpace = dwWinSpace - GetSpace(szPath);
|
|
if(szPath[0] != _pCif->GetInstallEngine()->GetInstallDrive())
|
|
{
|
|
szPath[0] = _pCif->GetInstallEngine()->GetInstallDrive();
|
|
dwInstallSpace = dwInstallSpace - GetSpace(szPath);
|
|
}
|
|
|
|
// log the space used
|
|
wsprintf(szCmd, "SpaceUsed: Windows drive: %d InstallDrive: %d\r\n", dwWinSpace, dwInstallSpace);
|
|
_pCif->GetInstallEngine()->WriteToLog(szCmd, FALSE);
|
|
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
|
|
HRESULT CCifComponent::_CopyAllUrls(LPCSTR pszTemp)
|
|
{
|
|
char szCompBuf[MAX_VALUE_LEN];
|
|
char szDest[MAX_PATH];
|
|
char szSource[MAX_PATH];
|
|
DWORD dwType;
|
|
HRESULT hr = NOERROR;
|
|
HANDLE hFind;
|
|
WIN32_FIND_DATA ffd;
|
|
char szBuf[MAX_PATH];
|
|
|
|
|
|
for(UINT i = 0; SUCCEEDED(hr) && SUCCEEDED(GetUrl(i, szCompBuf, sizeof(szCompBuf), &dwType)) ; i++)
|
|
{
|
|
_uPhase = INSTALLSTATUS_COPYING;
|
|
_pCif->GetInstallEngine()->OnComponentProgress(_szID, _uPhase, _szDesc, NULL, 0, 0);
|
|
|
|
lstrcpy(szSource, GetDownloadDir());
|
|
AddPath(szSource, ParseURLA(szCompBuf));
|
|
|
|
lstrcpy(szDest, pszTemp);
|
|
AddPath(szDest, ParseURLA(szCompBuf));
|
|
|
|
// Copy the file
|
|
if(!CopyFile(szSource, szDest, FALSE))
|
|
{
|
|
wsprintf(szLogBuf, "CopyFile failed for szSource=%s, szDest=%s, DLDir=%s\r\n", szSource, szDest, GetDownloadDir());
|
|
_pCif->GetInstallEngine()->WriteToLog(szLogBuf, FALSE);
|
|
hr = E_FILESMISSING;
|
|
}
|
|
|
|
if(SUCCEEDED(hr))
|
|
hr = _pCif->GetInstallEngine()->CheckForContinue();
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
_uPhase = INSTALLSTATUS_CHECKINGTRUST;
|
|
|
|
hr = _CheckForTrust(szSource, szDest);
|
|
if (hr == S_FALSE && !_pCif->GetInstallEngine()->IgnoreTrustCheck())
|
|
hr = TRUST_E_FAIL;
|
|
|
|
if(FAILED(hr))
|
|
{
|
|
DeleteFile(szSource);
|
|
}
|
|
}
|
|
|
|
if(SUCCEEDED(hr))
|
|
hr = _pCif->GetInstallEngine()->CheckForContinue();
|
|
|
|
if(SUCCEEDED(hr))
|
|
hr = _ExtractFiles(i, szDest, dwType);
|
|
|
|
if(SUCCEEDED(hr))
|
|
hr = _pCif->GetInstallEngine()->CheckForContinue();
|
|
|
|
|
|
}
|
|
|
|
// Now, if we're attempting an SR Lite install, then after
|
|
// extracting cab files to the temp directory...copy all of
|
|
// downloaded files to the temp directory.
|
|
if (_fUseSRLite)
|
|
{
|
|
lstrcpy(szSource, GetDownloadDir());
|
|
AddPath(szSource, "*.*");
|
|
|
|
if ( (hFind = FindFirstFile(szSource, &ffd)) != INVALID_HANDLE_VALUE)
|
|
{
|
|
do
|
|
{
|
|
if (ffd.dwFileAttributes != FILE_ATTRIBUTE_DIRECTORY)
|
|
{
|
|
lstrcpyn(szSource, GetDownloadDir(), sizeof(szSource));
|
|
SafeAddPath(szSource, ffd.cFileName, sizeof(szSource) - lstrlen(szSource));
|
|
|
|
lstrcpy(szDest, pszTemp);
|
|
AddPath(szDest, ffd.cFileName);
|
|
MoveFile(szSource, szDest);
|
|
}
|
|
} while (SUCCEEDED(hr) && FindNextFile(hFind, &ffd));
|
|
FindClose(hFind);
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CCifComponent::GetDetVersion(LPSTR pszDll, DWORD dwdllSize, LPSTR pszEntry, DWORD dwentSize)
|
|
{
|
|
char szBuf[MAX_VALUE_LEN];
|
|
HRESULT hr = E_FAIL;
|
|
|
|
if(pszDll && pszEntry)
|
|
*pszDll = *pszEntry = 0;
|
|
else
|
|
return hr;
|
|
|
|
if(GetPrivateProfileString(_szID, DETVERSION_KEY, "", szBuf, sizeof(szBuf), _pCif->GetCifPath()))
|
|
{
|
|
if((GetStringField(szBuf, 0, pszDll, dwdllSize) != 0) && (GetStringField(szBuf, 1, pszEntry, dwentSize) != 0))
|
|
{
|
|
hr = NOERROR;
|
|
}
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CCifComponent::_GetDetVerResult(LPCSTR pszDll, LPCSTR pszEntry, DETECTION_STRUCT *pDet, UINT *puStatus)
|
|
{
|
|
char szBuf[MAX_PATH];
|
|
HRESULT hr = E_FAIL;
|
|
HINSTANCE hLib;
|
|
DETECTVERSION fpDetVer;
|
|
|
|
*puStatus = ICI_NOTINSTALLED;
|
|
|
|
if (pszDll && pszEntry)
|
|
{
|
|
if(_hDetLib && (lstrcmpi(pszDll, _szDetDllName) == 0))
|
|
{
|
|
hLib = _hDetLib;
|
|
}
|
|
else
|
|
{
|
|
lstrcpy(szBuf, _pCif->GetCifPath());
|
|
GetParentDir(szBuf);
|
|
AddPath(szBuf, pszDll);
|
|
|
|
hLib = LoadLibrary(szBuf);
|
|
if (hLib == NULL)
|
|
{
|
|
// if Cif folder failed try IE folder before using searching path
|
|
if (SUCCEEDED(GetIEPath(szBuf, sizeof(szBuf))))
|
|
{
|
|
AddPath(szBuf, pszDll);
|
|
hLib = LoadLibrary(szBuf);
|
|
}
|
|
}
|
|
if(hLib)
|
|
{
|
|
lstrcpy(_szDetDllName, pszDll);
|
|
_hDetLib = hLib;
|
|
}
|
|
}
|
|
|
|
if (hLib)
|
|
{
|
|
fpDetVer = (DETECTVERSION)GetProcAddress(hLib, pszEntry);
|
|
if (fpDetVer)
|
|
{
|
|
switch(fpDetVer(pDet))
|
|
{
|
|
case DET_NOTINSTALLED:
|
|
*puStatus = ICI_NOTINSTALLED;
|
|
break;
|
|
|
|
case DET_INSTALLED:
|
|
*puStatus = ICI_INSTALLED;
|
|
break;
|
|
|
|
case DET_NEWVERSIONINSTALLED:
|
|
*puStatus = ICI_OLDVERSIONAVAILABLE;
|
|
break;
|
|
|
|
case DET_OLDVERSIONINSTALLED:
|
|
*puStatus = ICI_NEWVERSIONAVAILABLE;
|
|
break;
|
|
|
|
}
|
|
hr = NOERROR;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//=--------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=--------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
HRESULT CCifComponent::_CheckForTrust(LPCSTR pszURL, LPCSTR pszFilename)
|
|
{
|
|
HRESULT hr = S_FALSE;
|
|
|
|
// BUGBUG: Our internal workaround for non signed stuff
|
|
// if(rdwUrlFlags[i] & URLF_NOCHECKTRUST)
|
|
// return S_OK;
|
|
_uPhase = INSTALLSTATUS_CHECKINGTRUST;
|
|
|
|
_pCif->GetInstallEngine()->OnComponentProgress(_szID, _uPhase, _szDesc, NULL, 0, 0);
|
|
|
|
if(!_pCif->GetInstallEngine()->IgnoreTrustCheck())
|
|
hr = ::CheckTrustEx(pszURL, pszFilename, _pCif->GetInstallEngine()->GetHWND(), FALSE, NULL);
|
|
|
|
wsprintf(szLogBuf, " CheckTrust: %s, Result: %x (%s)\r\n", pszFilename, hr, SUCCEEDED(hr) ? STR_OK : STR_FAILED);
|
|
_pCif->GetInstallEngine()->WriteToLog(szLogBuf, TRUE);
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//=--------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=--------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
HRESULT CCifComponent::_ExtractFiles(UINT i, LPCSTR pszFile, DWORD dwType)
|
|
{
|
|
HRESULT hr = NOERROR;
|
|
char szPath[MAX_PATH];
|
|
char szExtractList[MAX_VALUE_LEN];
|
|
|
|
// Need to pay attention to rdwUrlFlags[i] to see if there is anything to do
|
|
if(dwType & URLF_EXTRACT)
|
|
{
|
|
_uPhase = INSTALLSTATUS_EXTRACTING;
|
|
|
|
_pCif->GetInstallEngine()->OnComponentProgress(_szID, _uPhase, _szDesc, NULL, 0, 0);
|
|
|
|
lstrcpy(szPath, pszFile);
|
|
GetParentDir(szPath);
|
|
|
|
GetFileExtractList(i, szExtractList, sizeof(szExtractList));
|
|
hr=ExtractFiles(pszFile, szPath, 0, lstrlen(szExtractList) ? szExtractList : NULL, NULL, 0);
|
|
|
|
wsprintf(szLogBuf, "File extraction: %s, Result: %x (%s)\r\n", pszFile, hr, SUCCEEDED(hr) ? STR_OK : STR_FAILED);
|
|
_pCif->GetInstallEngine()->WriteToLog(szLogBuf, TRUE);
|
|
|
|
// if the flag is set to delte the cab after an extract, do it
|
|
// I don't really care too much if this fails, at least not
|
|
// enough to fail this component
|
|
|
|
if(dwType & URLF_DELETE_AFTER_EXTRACT)
|
|
DeleteFile(pszFile);
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CCifComponent::_MarkComponentInstallStarted()
|
|
{
|
|
char szReg[MAX_PATH];
|
|
char szCompBuf[MAX_DISPLAYNAME_LENGTH];
|
|
HKEY hKey;
|
|
DWORD dwDumb;
|
|
|
|
lstrcpy(szReg, COMPONENT_KEY);
|
|
lstrcat(szReg, "\\");
|
|
|
|
GetGUID(szCompBuf, sizeof(szCompBuf));
|
|
lstrcat(szReg, szCompBuf);
|
|
if(RegOpenKeyEx( HKEY_LOCAL_MACHINE, szReg, 0,
|
|
KEY_READ | KEY_WRITE, &hKey) == ERROR_SUCCESS)
|
|
{
|
|
// Set IsInstalled=0
|
|
dwDumb = ISINSTALLED_NO;
|
|
RegSetValueExA(hKey, ISINSTALLED_KEY, 0, REG_DWORD,
|
|
(BYTE *) &dwDumb , sizeof(dwDumb));
|
|
|
|
// Delete StubPath so peruser isn't confused
|
|
RegDeleteValue(hKey, STUBPATH_KEY);
|
|
RegCloseKey(hKey);
|
|
}
|
|
}
|
|
|
|
|
|
BOOL CCifComponent::_CompareDownloadInfo()
|
|
{
|
|
char szCompBuf[MAX_VALUE_LEN];
|
|
char szInfoBuf[128];
|
|
DWORD dwCompVer, dwCompBuild, dwDLVer, dwDLBuild;
|
|
|
|
// first check this is the same language
|
|
GetPrivateProfileString(_szID, LOCALE_KEY, "", szInfoBuf, sizeof(szInfoBuf), _pCif->GetFilelist());
|
|
GetLocale(szCompBuf, sizeof(szCompBuf));
|
|
if(CompareLocales(szInfoBuf, szCompBuf) == 0)
|
|
{
|
|
// compare guids
|
|
GetPrivateProfileString(_szID, GUID_KEY, "", szInfoBuf, sizeof(szInfoBuf), _pCif->GetFilelist());
|
|
GetGUID(szCompBuf, sizeof(szCompBuf));
|
|
// intentionally let blank guid match to be backward compatible
|
|
if(lstrcmpi(szCompBuf, szInfoBuf) == 0)
|
|
{
|
|
|
|
GetPrivateProfileString(_szID, VERSION_KEY,"",szInfoBuf,
|
|
sizeof(szInfoBuf), _pCif->GetFilelist());
|
|
ConvertVersionStrToDwords(szInfoBuf, &dwDLVer, &dwDLBuild);
|
|
GetVersion(&dwCompVer, &dwCompBuild);
|
|
|
|
if((dwDLVer == dwCompVer) && (dwDLBuild == dwCompBuild))
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL CCifComponent::_FileIsDownloaded(LPCSTR pszFile, UINT i, DWORD *pdwSize)
|
|
{
|
|
HANDLE h;
|
|
DWORD dwSize, dwFileSize;
|
|
char szKey[16];
|
|
char szBuf[MAX_PATH];
|
|
|
|
szBuf[0] = '\0';
|
|
|
|
if(pdwSize)
|
|
*pdwSize = 0;
|
|
|
|
wsprintf(szKey, "URL%d", i);
|
|
GetPrivateProfileString(_szID, szKey,"0",szBuf,
|
|
sizeof(szBuf), _pCif->GetFilelist());
|
|
dwSize = GetIntField(szBuf, 0, 0);
|
|
|
|
if(dwSize == 0)
|
|
return FALSE;
|
|
|
|
if (_fUseSRLite && lstrlen(GetDownloadDir()) != 0)
|
|
lstrcpy(szBuf, GetDownloadDir());
|
|
else
|
|
lstrcpy(szBuf, _pCif->GetDownloadDir());
|
|
|
|
AddPath(szBuf, pszFile);
|
|
dwFileSize = MyGetFileSize(szBuf);
|
|
/*
|
|
// Open the file
|
|
h = CreateFile(pszFile, GENERIC_READ, 0, NULL,
|
|
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
|
|
if(h == INVALID_HANDLE_VALUE)
|
|
return FALSE;
|
|
|
|
// dont worry about files over 4 gig
|
|
dwFileSize = GetFileSize(h, NULL);
|
|
CloseHandle(h);
|
|
*/
|
|
if(dwFileSize == dwSize)
|
|
{
|
|
if(pdwSize)
|
|
*pdwSize = dwFileSize;
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
//=--------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=--------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
void CCifComponent::_MarkAsInstalled()
|
|
{
|
|
CHAR szCompBuf[MAX_VALUE_LEN];
|
|
HKEY hComponentKey = NULL;
|
|
HKEY hGUIDKey = NULL;
|
|
DWORD dwDumb, dwVer, dwBuild;
|
|
LPSTR psz;
|
|
|
|
if(RegCreateKeyExA(HKEY_LOCAL_MACHINE, COMPONENT_KEY, 0, 0, 0,
|
|
KEY_WRITE, NULL, &hComponentKey, &dwDumb) == ERROR_SUCCESS)
|
|
{
|
|
GetGUID(szCompBuf, sizeof(szCompBuf));
|
|
if(RegCreateKeyExA(hComponentKey, szCompBuf, 0, 0, 0, KEY_WRITE, NULL, &hGUIDKey, &dwDumb) == ERROR_SUCCESS)
|
|
{
|
|
// we only write to the key if this guy is NOT active setup aware
|
|
if(IsActiveSetupAware() == S_FALSE)
|
|
{
|
|
// write Display name to Default
|
|
GetDescription(szCompBuf, sizeof(szCompBuf));
|
|
RegSetValueExA(hGUIDKey, NULL, 0, REG_SZ, (BYTE *)szCompBuf , lstrlen(szCompBuf) + 1 );
|
|
|
|
// write component ID
|
|
GetID(szCompBuf, sizeof(szCompBuf));
|
|
RegSetValueExA(hGUIDKey, "ComponentID", 0, REG_SZ, (BYTE *)szCompBuf , lstrlen(szCompBuf) + 1 );
|
|
|
|
// write out version
|
|
GetVersion(&dwVer, &dwBuild);
|
|
wsprintf(szCompBuf, "%d,%d,%d,%d", HIWORD(dwVer),LOWORD(dwVer),HIWORD(dwBuild),LOWORD(dwBuild));
|
|
RegSetValueExA(hGUIDKey, VERSION_KEY, 0, REG_SZ, (BYTE *)szCompBuf , lstrlen(szCompBuf) + 1);
|
|
|
|
// write out locale
|
|
GetLocale(szCompBuf, sizeof(szCompBuf));
|
|
RegSetValueExA(hGUIDKey, LOCALE_KEY, 0, REG_SZ, (BYTE *)szCompBuf , lstrlen(szCompBuf) + 1);
|
|
|
|
// Write out "IsInstalled=1"
|
|
dwDumb = ISINSTALLED_YES;
|
|
RegSetValueExA(hGUIDKey, ISINSTALLED_KEY, 0, REG_DWORD, (BYTE *) &dwDumb , sizeof(dwDumb));
|
|
}
|
|
}
|
|
}
|
|
|
|
if(hComponentKey)
|
|
RegCloseKey(hComponentKey);
|
|
|
|
if(hGUIDKey)
|
|
RegCloseKey(hGUIDKey);
|
|
}
|
|
|
|
|
|
void CCifComponent::_MarkFileDownloadFinished(LPCSTR pszFilePath, UINT i, LPCSTR pszFilename)
|
|
{
|
|
char szSize[MAX_PATH];
|
|
char szKey[16];
|
|
DWORD dwFileSize;
|
|
HANDLE h;
|
|
|
|
// put any entry in filelist.dat
|
|
// [CompID]
|
|
// URLi=Filesize
|
|
|
|
dwFileSize = MyGetFileSize(pszFilePath);
|
|
/*
|
|
// Create the file
|
|
h = CreateFile(pszFilePath, GENERIC_READ, 0, NULL,
|
|
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
|
|
if(h == INVALID_HANDLE_VALUE)
|
|
return;
|
|
|
|
// dont worry about files over 4 gig
|
|
dwFileSize = GetFileSize(h, NULL);
|
|
CloseHandle(h);
|
|
*/
|
|
if(dwFileSize != 0xffffffff)
|
|
{
|
|
wsprintf(szKey, "URL%d", i);
|
|
wsprintf(szSize, "%d,%s", dwFileSize, pszFilename);
|
|
|
|
WritePrivateProfileString(_szID, szKey, szSize, _pCif->GetFilelist());
|
|
|
|
// need to flush the pszFileList file; otherwise, with Stacker installed,
|
|
// it GPFs when trying to open the file in another thread (bug #13041)
|
|
WritePrivateProfileString(NULL, NULL, NULL, _pCif->GetFilelist());
|
|
}
|
|
}
|
|
|
|
void CCifComponent::_MarkFileDownloadStarted(UINT i)
|
|
{
|
|
char szKey[10];
|
|
|
|
wsprintf(szKey, "URL%d", i);
|
|
|
|
WritePrivateProfileString(_szID, szKey, NULL, _pCif->GetFilelist());
|
|
|
|
// flush -- fixes the Stacker bug #13041
|
|
WritePrivateProfileString(NULL, NULL, NULL, _pCif->GetFilelist());
|
|
}
|
|
|
|
|
|
void CCifComponent::_MarkDownloadStarted()
|
|
{
|
|
char szCompBuf[MAX_VALUE_LEN];
|
|
DWORD dwVer, dwBuild;
|
|
|
|
// if the section doesn't match what we expect, we kill
|
|
// section so we will redownload everything
|
|
if(!_CompareDownloadInfo())
|
|
WritePrivateProfileSection(_szID, NULL, _pCif->GetFilelist());
|
|
|
|
// write the version
|
|
GetVersion(&dwVer, &dwBuild);
|
|
wsprintf(szCompBuf, "%d,%d,%d,%d", HIWORD(dwVer),LOWORD(dwVer),HIWORD(dwBuild),LOWORD(dwBuild));
|
|
WritePrivateProfileString(_szID, VERSION_KEY, szCompBuf, _pCif->GetFilelist());
|
|
|
|
// write locale
|
|
GetLocale(szCompBuf, sizeof(szCompBuf));
|
|
WritePrivateProfileString(_szID, LOCALE_KEY, szCompBuf, _pCif->GetFilelist());
|
|
|
|
// write the guid
|
|
GetGUID(szCompBuf, sizeof(szCompBuf));
|
|
WritePrivateProfileString(_szID, GUID_KEY, szCompBuf, _pCif->GetFilelist());
|
|
|
|
// flush -- fixes the Stacker bug #13041
|
|
WritePrivateProfileString(NULL, NULL, NULL, _pCif->GetFilelist());
|
|
}
|
|
|
|
HRESULT CCifComponent::_CheckForDependencies()
|
|
{
|
|
char szCompBuf[MAX_ID_LENGTH];
|
|
char chType;
|
|
ICifComponent *pcomp;
|
|
HRESULT hr = NOERROR;
|
|
DWORD dwNeedVer, dwNeedBuild, dwInsVer, dwInsBuild;
|
|
|
|
for(int i = 0; SUCCEEDED(GetDependency(i, szCompBuf, sizeof(szCompBuf), &chType, &dwNeedVer, &dwNeedBuild)); i++)
|
|
{
|
|
if(SUCCEEDED(_pCif->FindComponent(szCompBuf, &pcomp)))
|
|
{
|
|
if(chType != DEP_BUDDY)
|
|
{
|
|
UINT uStatus = pcomp->IsThisVersionInstalled(dwNeedVer, dwNeedBuild, &dwInsVer, &dwInsBuild);
|
|
if( (uStatus == ICI_NOTINSTALLED) || (uStatus == ICI_NEWVERSIONAVAILABLE) )
|
|
{
|
|
hr = E_FAIL;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CCifComponent::_SRLiteDownloadFiles()
|
|
{
|
|
HANDLE hFile;
|
|
WIN32_FIND_DATA ffd = {0};
|
|
CHAR szFile[MAX_PATH];
|
|
LPSTR pszFile = NULL;
|
|
HRESULT hr = S_OK;
|
|
CHAR szCompBuf[INTERNET_MAX_URL_LENGTH];
|
|
DWORD dwType;
|
|
BOOL fRet;
|
|
UINT uPatchCount = 0;
|
|
|
|
_uPhase = INSTALLSTATUS_DOWNLOADING;
|
|
|
|
// Look for presence of [DownloadFileSection] in a single
|
|
// .inf file extracted from the cabs.
|
|
for(UINT i = 0; SUCCEEDED(hr) && SUCCEEDED(GetUrl(i, szCompBuf, sizeof(szCompBuf), &dwType)) ; i++)
|
|
{
|
|
TCHAR szShortPath[MAX_PATH] = "";
|
|
GetShortPathName(GetDownloadDir(), szShortPath, sizeof(szShortPath));
|
|
// If all goes well, we should just get a single INF file extracted
|
|
lstrcpyn(szFile, GetDownloadDir(), sizeof(szFile));
|
|
SafeAddPath(szFile, szCompBuf, sizeof(szCompBuf));
|
|
|
|
hr = ExtractFiles(szFile, szShortPath, 0, NULL, NULL, 0);
|
|
wsprintf(szLogBuf, "Extracting empty cabs for %s in %s returned 0x%lx\r\n", szCompBuf, szShortPath, hr);
|
|
_pCif->GetInstallEngine()->WriteToLog(szLogBuf, FALSE);
|
|
}
|
|
|
|
lstrcpyn(szFile, GetDownloadDir(), sizeof(szFile));
|
|
SafeAddPath(szFile, "*.inf", sizeof(szFile));
|
|
|
|
// Get the file count because we're going to hack the
|
|
// progress bar UI since we don't know the real download sizes
|
|
// for the patch INFs upfront.
|
|
hFile = FindFirstFile(szFile, &ffd);
|
|
if (hFile != INVALID_HANDLE_VALUE)
|
|
{
|
|
do
|
|
{
|
|
// Strip filename from path
|
|
lstrcpyn(szFile, GetDownloadDir(), sizeof(szFile));
|
|
SafeAddPath(szFile, ffd.cFileName, sizeof(szFile) - lstrlen(szFile));
|
|
|
|
if (IsPatchableINF(szFile))
|
|
{
|
|
uPatchCount++;
|
|
}
|
|
} while (FindNextFile(hFile, &ffd));
|
|
FindClose(hFile);
|
|
}
|
|
|
|
lstrcpyn(szFile, GetDownloadDir(), sizeof(szFile));
|
|
SafeAddPath(szFile, "*.inf", sizeof(szFile));
|
|
|
|
hFile = FindFirstFile(szFile, &ffd);
|
|
|
|
// No need to keep the grep pattern...
|
|
lstrcpyn(szFile, GetDownloadDir(), sizeof(szFile));
|
|
pszFile = szFile + lstrlen(szFile);
|
|
|
|
if (hFile != INVALID_HANDLE_VALUE)
|
|
{
|
|
do
|
|
{
|
|
// Strip filename from path
|
|
lstrcpyn(szFile, GetDownloadDir(), sizeof(szFile));
|
|
SafeAddPath(szFile, ffd.cFileName, sizeof(szFile) - lstrlen(szFile));
|
|
|
|
if (IsPatchableINF(szFile))
|
|
{
|
|
fRet = TRUE;
|
|
// Found an inf that supports SR Lite. Try downloading the patch files.
|
|
// Use our downloader wrapper for the advpack extension to do the
|
|
// downloading.
|
|
hr = _pCif->GetInstallEngine()->GetPatchDownloader()->SetupDownload(_uTotalGoal, uPatchCount, (IMyDownloadCallback *) this, GetDownloadDir());
|
|
hr = _pCif->GetInstallEngine()->GetPatchDownloader()->DoDownload(szFile);
|
|
}
|
|
else
|
|
{
|
|
wsprintf(szLogBuf, "%s INF found with no DownloadFileSection\r\n", szFile);
|
|
_pCif->GetInstallEngine()->WriteToLog(szLogBuf, FALSE);
|
|
}
|
|
|
|
_uTotalProgress += _uIndivProgress;
|
|
|
|
} while (SUCCEEDED(hr) && FindNextFile(hFile, &ffd));
|
|
FindClose(hFile);
|
|
}
|
|
|
|
if (!fRet || !SUCCEEDED(hr))
|
|
{
|
|
wsprintf(szLogBuf, "Either no INF was found with a DownloadFileSection or an error occured during processing\r\n");
|
|
_pCif->GetInstallEngine()->WriteToLog(szLogBuf, FALSE);
|
|
return E_FAIL;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
void CCifComponent::SetDownloadDir(LPCSTR pszDownloadDir)
|
|
{
|
|
if (pszDownloadDir)
|
|
lstrcpyn(_szDLDir, pszDownloadDir, MAX_PATH);
|
|
}
|
|
|
|
//========= ICifRWComponent implementation ================================================
|
|
//
|
|
CCifRWComponent::CCifRWComponent(LPCSTR pszID, CCifFile *pCif) : CCifComponent(pszID, pCif)
|
|
{
|
|
}
|
|
|
|
CCifRWComponent::~CCifRWComponent()
|
|
{
|
|
}
|
|
|
|
STDMETHODIMP CCifRWComponent::GetID(LPSTR pszID, DWORD dwSize)
|
|
{
|
|
return(CCifComponent::GetID(pszID, dwSize));
|
|
}
|
|
|
|
STDMETHODIMP CCifRWComponent::GetGUID(LPSTR pszGUID, DWORD dwSize)
|
|
{
|
|
return(CCifComponent::GetGUID(pszGUID, dwSize));
|
|
}
|
|
|
|
STDMETHODIMP CCifRWComponent::GetDescription(LPSTR pszDesc, DWORD dwSize)
|
|
{
|
|
return(CCifComponent::GetDescription(pszDesc, dwSize));
|
|
}
|
|
|
|
STDMETHODIMP CCifRWComponent::GetDetails(LPSTR pszDetails, DWORD dwSize)
|
|
{
|
|
return(CCifComponent::GetDetails(pszDetails, dwSize));
|
|
}
|
|
|
|
STDMETHODIMP CCifRWComponent::GetUrl(UINT uUrlNum, LPSTR pszUrl, DWORD dwSize, LPDWORD pdwUrlFlags)
|
|
{
|
|
return(CCifComponent::GetUrl(uUrlNum, pszUrl, dwSize, pdwUrlFlags));
|
|
}
|
|
|
|
STDMETHODIMP CCifRWComponent::GetFileExtractList(UINT uUrlNum, LPSTR pszExtract, DWORD dwSize)
|
|
{
|
|
return(CCifComponent::GetFileExtractList(uUrlNum, pszExtract, dwSize));
|
|
}
|
|
|
|
STDMETHODIMP CCifRWComponent::GetUrlCheckRange(UINT uUrlNum, LPDWORD pdwMin, LPDWORD pdwMax)
|
|
{
|
|
return(CCifComponent::GetUrlCheckRange(uUrlNum, pdwMin, pdwMax));
|
|
}
|
|
|
|
STDMETHODIMP CCifRWComponent::GetCommand(UINT uCmdNum, LPSTR pszCmd, DWORD dwCmdSize, LPSTR pszSwitches,
|
|
DWORD dwSwitchSize, LPDWORD pdwType)
|
|
{
|
|
return(CCifComponent::GetCommand(uCmdNum, pszCmd, dwCmdSize, pszSwitches, dwSwitchSize, pdwType));
|
|
}
|
|
|
|
STDMETHODIMP CCifRWComponent::GetVersion(LPDWORD pdwVersion, LPDWORD pdwBuild)
|
|
{
|
|
return(CCifComponent::GetVersion(pdwVersion, pdwBuild));
|
|
}
|
|
|
|
STDMETHODIMP CCifRWComponent::GetLocale(LPSTR pszLocale, DWORD dwSize)
|
|
{
|
|
return(CCifComponent::GetLocale(pszLocale, dwSize));
|
|
}
|
|
|
|
STDMETHODIMP CCifRWComponent::GetUninstallKey(LPSTR pszKey, DWORD dwSize)
|
|
{
|
|
return(CCifComponent::GetUninstallKey(pszKey, dwSize));
|
|
}
|
|
|
|
STDMETHODIMP CCifRWComponent::GetInstalledSize(LPDWORD pdwWin, LPDWORD pdwApp)
|
|
{
|
|
return(CCifComponent::GetInstalledSize(pdwWin, pdwApp));
|
|
}
|
|
|
|
STDMETHODIMP_(DWORD) CCifRWComponent::GetDownloadSize()
|
|
{
|
|
return(CCifComponent::GetDownloadSize());
|
|
}
|
|
|
|
STDMETHODIMP_(DWORD) CCifRWComponent::GetExtractSize()
|
|
{
|
|
return(CCifComponent::GetExtractSize());
|
|
}
|
|
|
|
STDMETHODIMP CCifRWComponent::GetSuccessKey(LPSTR pszKey, DWORD dwSize)
|
|
{
|
|
return(CCifComponent::GetSuccessKey(pszKey, dwSize));
|
|
}
|
|
|
|
STDMETHODIMP CCifRWComponent::GetProgressKeys(LPSTR pszProgress, DWORD dwProgSize,
|
|
LPSTR pszCancel, DWORD dwCancelSize)
|
|
{
|
|
return(CCifComponent::GetProgressKeys(pszProgress, dwProgSize, pszCancel, dwCancelSize));
|
|
}
|
|
|
|
STDMETHODIMP CCifRWComponent::IsActiveSetupAware()
|
|
{
|
|
return(CCifComponent::IsActiveSetupAware());
|
|
}
|
|
|
|
STDMETHODIMP CCifRWComponent::IsRebootRequired()
|
|
{
|
|
return(CCifComponent::IsActiveSetupAware());
|
|
}
|
|
|
|
STDMETHODIMP CCifRWComponent::RequiresAdminRights()
|
|
{
|
|
return(CCifComponent::RequiresAdminRights());
|
|
}
|
|
|
|
STDMETHODIMP_(DWORD) CCifRWComponent::GetPriority()
|
|
{
|
|
return(CCifComponent::GetPriority());
|
|
}
|
|
|
|
STDMETHODIMP CCifRWComponent::GetDependency(UINT uDepNum, LPSTR pszID, DWORD dwBuf, char *pchType, LPDWORD pdwVer, LPDWORD pdwBuild)
|
|
{
|
|
return(CCifComponent::GetDependency(uDepNum, pszID, dwBuf, pchType, pdwVer, pdwBuild));
|
|
}
|
|
|
|
STDMETHODIMP_(DWORD) CCifRWComponent::GetPlatform()
|
|
{
|
|
return(CCifComponent::GetPlatform());
|
|
}
|
|
|
|
STDMETHODIMP CCifRWComponent::GetMode(UINT uModeNum, LPSTR pszModes, DWORD dwSize)
|
|
{
|
|
return(CCifComponent::GetMode(uModeNum, pszModes, dwSize));
|
|
}
|
|
|
|
STDMETHODIMP CCifRWComponent::GetTreatAsOneComponents(UINT uNum, LPSTR pszID, DWORD dwBuf)
|
|
{
|
|
return(CCifComponent::GetTreatAsOneComponents(uNum, pszID, dwBuf));
|
|
}
|
|
|
|
STDMETHODIMP CCifRWComponent::GetCustomData(LPSTR pszKey, LPSTR pszData, DWORD dwSize)
|
|
{
|
|
return(CCifComponent::GetCustomData(pszKey, pszData, dwSize));
|
|
}
|
|
|
|
STDMETHODIMP CCifRWComponent::GetGroup(LPSTR pszID, DWORD dwSize)
|
|
{
|
|
return(CCifComponent::GetGroup(pszID, dwSize));
|
|
}
|
|
|
|
STDMETHODIMP CCifRWComponent::IsUIVisible()
|
|
{
|
|
return(CCifComponent::IsUIVisible());
|
|
}
|
|
|
|
STDMETHODIMP CCifRWComponent::GetPatchID(LPSTR pszID, DWORD dwSize)
|
|
{
|
|
return(CCifComponent::GetPatchID(pszID, dwSize));
|
|
}
|
|
|
|
STDMETHODIMP_(DWORD) CCifRWComponent::IsComponentInstalled()
|
|
{
|
|
return(CCifComponent::IsComponentInstalled());
|
|
}
|
|
|
|
STDMETHODIMP CCifRWComponent::IsComponentDownloaded()
|
|
{
|
|
return(CCifComponent::IsComponentDownloaded());
|
|
}
|
|
|
|
STDMETHODIMP_(DWORD) CCifRWComponent::IsThisVersionInstalled(DWORD dwAskVer, DWORD dwAskBld, LPDWORD pdwVersion, LPDWORD pdwBuild)
|
|
{
|
|
return(CCifComponent::IsThisVersionInstalled(dwAskVer, dwAskBld, pdwVersion, pdwBuild));
|
|
}
|
|
|
|
STDMETHODIMP_(DWORD) CCifRWComponent::GetInstallQueueState()
|
|
{
|
|
return(CCifComponent::GetInstallQueueState());
|
|
}
|
|
|
|
STDMETHODIMP CCifRWComponent::SetInstallQueueState(DWORD dwState)
|
|
{
|
|
return(CCifComponent::SetInstallQueueState(dwState));
|
|
}
|
|
|
|
STDMETHODIMP_(DWORD) CCifRWComponent::GetActualDownloadSize()
|
|
{
|
|
return(CCifComponent::GetActualDownloadSize());
|
|
}
|
|
|
|
STDMETHODIMP_(DWORD) CCifRWComponent::GetCurrentPriority()
|
|
{
|
|
return(CCifComponent::GetCurrentPriority());
|
|
}
|
|
|
|
STDMETHODIMP CCifRWComponent::SetCurrentPriority(DWORD dwPriority)
|
|
{
|
|
return(CCifComponent::SetCurrentPriority(dwPriority));
|
|
}
|
|
|
|
|
|
STDMETHODIMP CCifRWComponent:: GetDetVersion(LPSTR pszDLL, DWORD dwdllSize, LPSTR pszEntry, DWORD dwentSize)
|
|
{
|
|
return(CCifComponent::GetDetVersion(pszDLL, dwdllSize, pszEntry, dwentSize));
|
|
}
|
|
|
|
|
|
STDMETHODIMP CCifRWComponent::SetGUID(LPCSTR pszGUID)
|
|
{
|
|
return (WritePrivateProfileString(_szID, GUID_KEY, pszGUID, _pCif->GetCifPath())? NOERROR:E_FAIL);
|
|
}
|
|
|
|
STDMETHODIMP CCifRWComponent::SetDescription(LPCSTR pszDesc)
|
|
{
|
|
return (WriteTokenizeString(_pCif->GetCifPath(), _szID, DISPLAYNAME_KEY, pszDesc));
|
|
}
|
|
|
|
STDMETHODIMP CCifRWComponent::SetDetails(LPCSTR pszDesc)
|
|
{
|
|
return (WriteTokenizeString(_pCif->GetCifPath(), _szID, DETAILS_KEY, pszDesc));
|
|
}
|
|
|
|
STDMETHODIMP CCifRWComponent::SetVersion(LPCSTR pszVersion)
|
|
{
|
|
return (WritePrivateProfileString(_szID, VERSION_KEY, pszVersion, _pCif->GetCifPath())? NOERROR:E_FAIL);
|
|
}
|
|
|
|
STDMETHODIMP CCifRWComponent::SetUninstallKey(LPCSTR pszKey)
|
|
{
|
|
return (MyWritePrivateProfileString(_szID, UNINSTALLSTRING_KEY, pszKey, _pCif->GetCifPath())? NOERROR:E_FAIL);
|
|
}
|
|
|
|
STDMETHODIMP CCifRWComponent::SetInstalledSize(DWORD dwWin, DWORD dwApp)
|
|
{
|
|
char szBuf[50];
|
|
|
|
wsprintf(szBuf,"%d,%d", dwWin, dwApp);
|
|
return (WritePrivateProfileString(_szID, INSTALLSIZE_KEY, szBuf, _pCif->GetCifPath())? NOERROR:E_FAIL);
|
|
}
|
|
|
|
STDMETHODIMP CCifRWComponent::SetDownloadSize(DWORD dwSize)
|
|
{
|
|
char szBuf1[MAX_VALUE_LEN];
|
|
char szBuf2[MAX_VALUE_LEN];
|
|
DWORD dwExtractSize;
|
|
|
|
szBuf1[0] = '\0';
|
|
|
|
// Read in size
|
|
GetPrivateProfileString(_szID, SIZE_KEY, "0", szBuf1, sizeof(szBuf1), _pCif->GetCifPath());
|
|
dwExtractSize = GetIntField(szBuf1, 1, (DWORD)-1);
|
|
if (dwExtractSize == (DWORD)-1)
|
|
wsprintf(szBuf2,"%d", dwSize);
|
|
else
|
|
wsprintf(szBuf2,"%d,%d", dwSize, dwExtractSize);
|
|
return (WritePrivateProfileString(_szID, SIZE_KEY, szBuf2, _pCif->GetCifPath())? NOERROR:E_FAIL);
|
|
}
|
|
|
|
STDMETHODIMP CCifRWComponent::SetExtractSize(DWORD dwSize)
|
|
{
|
|
char szBuf1[MAX_VALUE_LEN];
|
|
char szBuf2[MAX_VALUE_LEN];
|
|
|
|
szBuf1[0] = '\0';
|
|
|
|
// Read in size
|
|
GetPrivateProfileString(_szID, SIZE_KEY, "0,0", szBuf1, sizeof(szBuf1), _pCif->GetCifPath());
|
|
wsprintf(szBuf2,"%d,%d", GetIntField(szBuf1, 0, 0), dwSize);
|
|
return (WritePrivateProfileString(_szID, SIZE_KEY, szBuf2, _pCif->GetCifPath())? NOERROR:E_FAIL);
|
|
}
|
|
|
|
STDMETHODIMP CCifRWComponent::DeleteDependency(LPCSTR pszID, char chType)
|
|
{
|
|
HRESULT hr;
|
|
|
|
if (pszID == NULL) //delete all from all modes
|
|
hr = WritePrivateProfileString(_szID, DEPENDENCY_KEY, NULL, _pCif->GetCifPath())?NOERROR:E_FAIL;
|
|
else
|
|
{
|
|
// delete only the given ones
|
|
char szBuf[MAX_VALUE_LEN];
|
|
char szBufIn[MAX_VALUE_LEN];
|
|
char szBufOut[MAX_VALUE_LEN];
|
|
char szOne[MAX_ID_LENGTH];
|
|
LPSTR pszTmp;
|
|
UINT i = 0;
|
|
|
|
szBufOut[0] =0;
|
|
wsprintf( szBuf, "%s:%c", pszID, chType);
|
|
if (GetPrivateProfileString(_szID, DEPENDENCY_KEY, "", szBufIn, sizeof(szBufIn), _pCif->GetCifPath()))
|
|
{
|
|
pszTmp = szBufOut;
|
|
while(GetStringField(szBufIn, i++, szOne, sizeof(szOne)))
|
|
{
|
|
if (lstrcmpi(szOne, szBuf))
|
|
{
|
|
if ( i != 1)
|
|
{
|
|
lstrcpy(pszTmp,",");
|
|
pszTmp++;
|
|
}
|
|
lstrcpy(pszTmp, szOne);
|
|
pszTmp = pszTmp + lstrlen(szOne);
|
|
}
|
|
}
|
|
hr = WritePrivateProfileString(_szID, DEPENDENCY_KEY, szBufOut, _pCif->GetCifPath())? NOERROR:E_FAIL;
|
|
}
|
|
}
|
|
return hr;
|
|
|
|
}
|
|
|
|
STDMETHODIMP CCifRWComponent::AddDependency(LPCSTR pszID, char chType)
|
|
{
|
|
char szBuf[MAX_VALUE_LEN];
|
|
char szBuf1[MAX_VALUE_LEN];
|
|
char szOne[MAX_ID_LENGTH];
|
|
LPSTR pszTmp;
|
|
UINT i = 0;
|
|
BOOL bFound = FALSE;
|
|
HRESULT hr = NOERROR;
|
|
|
|
if (pszID==NULL)
|
|
return hr;
|
|
|
|
if (chType == '\\')
|
|
wsprintf( szBuf1, "%s:N:6.0.0.0", pszID, chType);
|
|
else
|
|
wsprintf( szBuf1, "%s:%c", pszID, chType);
|
|
|
|
if (GetPrivateProfileString(_szID, DEPENDENCY_KEY, "", szBuf, sizeof(szBuf), _pCif->GetCifPath()))
|
|
{
|
|
while(GetStringField(szBuf, i++, szOne, sizeof(szOne)))
|
|
{
|
|
if (lstrcmpi(szOne, szBuf1) == 0)
|
|
{
|
|
// found it, no need to add
|
|
bFound = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
if (!bFound)
|
|
{
|
|
LPSTR pszTmp = szBuf + lstrlen(szBuf);
|
|
lstrcpy(pszTmp, ",");
|
|
pszTmp++;
|
|
lstrcpy(pszTmp, szBuf1);
|
|
hr = WritePrivateProfileString(_szID, DEPENDENCY_KEY, szBuf, _pCif->GetCifPath())? NOERROR:E_FAIL;
|
|
}
|
|
}
|
|
else
|
|
hr = WritePrivateProfileString(_szID, DEPENDENCY_KEY, szBuf1, _pCif->GetCifPath())? NOERROR:E_FAIL;
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CCifRWComponent::SetUIVisible(BOOL bFlag)
|
|
{
|
|
return (WritePrivateProfileString(_szID, UIVISIBLE_KEY, bFlag? "1" : "0", _pCif->GetCifPath())? NOERROR:E_FAIL);
|
|
}
|
|
|
|
STDMETHODIMP CCifRWComponent::SetGroup(LPCSTR pszID)
|
|
{
|
|
return (WritePrivateProfileString(_szID, GROUP_KEY, pszID, _pCif->GetCifPath())? NOERROR:E_FAIL);
|
|
}
|
|
|
|
STDMETHODIMP CCifRWComponent::SetPlatform(DWORD dwPlatform)
|
|
{
|
|
char szBuf[MAX_VALUE_LEN];
|
|
char *rszPlatforms[7] = { STR_WIN95, STR_WIN98, STR_NT4, STR_NT5, STR_NT4ALPHA, STR_NT5ALPHA, STR_MILLEN };
|
|
DWORD rdwPlatforms[] = { PLATFORM_WIN95, PLATFORM_WIN98, PLATFORM_NT4, PLATFORM_NT5,
|
|
PLATFORM_NT4ALPHA, PLATFORM_NT5ALPHA, PLATFORM_MILLEN };
|
|
|
|
_dwPlatform = dwPlatform;
|
|
szBuf[0] = 0;
|
|
|
|
for(int i = 0; i < 7; i++)
|
|
{
|
|
if(dwPlatform & rdwPlatforms[i])
|
|
{
|
|
lstrcat(szBuf, rszPlatforms[i]);
|
|
lstrcat(szBuf, ",");
|
|
}
|
|
}
|
|
|
|
return (WritePrivateProfileString(_szID, PLATFORM_KEY, szBuf, _pCif->GetCifPath())? NOERROR:E_FAIL);
|
|
}
|
|
|
|
STDMETHODIMP CCifRWComponent::SetPriority(DWORD dwPri)
|
|
{
|
|
char szBuf[MAX_SMALL_BUF];
|
|
|
|
wsprintf(szBuf, "%d", dwPri);
|
|
return (WritePrivateProfileString(_szID, PRIORITY, szBuf, _pCif->GetCifPath())? NOERROR:E_FAIL);
|
|
}
|
|
|
|
STDMETHODIMP CCifRWComponent::SetReboot(BOOL bReboot)
|
|
{
|
|
return (WritePrivateProfileString(_szID, REBOOT_KEY, bReboot? "1":"0", _pCif->GetCifPath())? NOERROR:E_FAIL);
|
|
}
|
|
|
|
STDMETHODIMP CCifRWComponent::SetCommand(UINT uCmdNum, LPCSTR pszCmd, LPCSTR pszSwitches, DWORD dwType)
|
|
{
|
|
char szKey[16];
|
|
char szType[10];
|
|
HRESULT hr = NOERROR;
|
|
|
|
uCmdNum++;
|
|
wsprintf(szKey, "%s%lu", CMD_KEY, uCmdNum);
|
|
if (!MyWritePrivateProfileString(_szID, szKey, pszCmd, _pCif->GetCifPath()))
|
|
hr = E_FAIL;
|
|
wsprintf(szKey, "%s%lu", ARGS_KEY, uCmdNum);
|
|
if(!MyWritePrivateProfileString(_szID, szKey, (pszCmd==NULL)?NULL:pszSwitches, _pCif->GetCifPath()))
|
|
hr = E_FAIL;
|
|
wsprintf(szKey, "%s%lu", TYPE_KEY, uCmdNum);
|
|
wsprintf(szType,"%d", dwType);
|
|
if(!WritePrivateProfileString(_szID, szKey, (pszCmd==NULL)? NULL:szType, _pCif->GetCifPath()))
|
|
hr = E_FAIL;
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CCifRWComponent::SetUrl(UINT uUrlNum, LPCSTR pszUrl, DWORD dwUrlFlags)
|
|
{
|
|
char szKey[16];
|
|
char szBuf[MAX_VALUE_LEN];
|
|
HRESULT hr = NOERROR;
|
|
|
|
uUrlNum++;
|
|
wsprintf(szKey, "%s%lu", URL_KEY, uUrlNum);
|
|
wsprintf(szBuf, "\"%s\",%d", pszUrl, dwUrlFlags);
|
|
if (!WritePrivateProfileString(_szID, szKey, szBuf, _pCif->GetCifPath()))
|
|
hr = E_FAIL;
|
|
wsprintf(szKey, "%s%lu", SIZE_KEY, uUrlNum);
|
|
if(!WritePrivateProfileString(_szID, szKey, NULL, _pCif->GetCifPath()))
|
|
hr = E_FAIL;
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CCifRWComponent::DeleteFromModes(LPCSTR pszMode)
|
|
{
|
|
HRESULT hr;
|
|
|
|
if (pszMode == NULL) //delete all from all modes
|
|
hr = WritePrivateProfileString(_szID, MODES_KEY, pszMode, _pCif->GetCifPath())?NOERROR:E_FAIL;
|
|
else
|
|
{
|
|
// delete only the given ones
|
|
char szBufIn[MAX_VALUE_LEN];
|
|
char szBufOut[MAX_VALUE_LEN];
|
|
char szOneMode[MAX_ID_LENGTH];
|
|
LPSTR pszTmp;
|
|
UINT i = 0;
|
|
|
|
szBufOut[0] =0;
|
|
if (SUCCEEDED(MyTranslateString(_pCif->GetCifPath(), _szID, MODES_KEY, szBufIn, sizeof(szBufIn))))
|
|
{
|
|
pszTmp = szBufOut;
|
|
while(GetStringField(szBufIn, i++, szOneMode, sizeof(szOneMode)))
|
|
{
|
|
if (lstrcmpi(szOneMode, pszMode))
|
|
{
|
|
if ( i != 1)
|
|
{
|
|
lstrcpy(pszTmp,",");
|
|
pszTmp++;
|
|
}
|
|
lstrcpy(pszTmp, szOneMode);
|
|
pszTmp = pszTmp + lstrlen(szOneMode);
|
|
}
|
|
}
|
|
hr = WriteTokenizeString(_pCif->GetCifPath(), _szID, MODES_KEY, szBufOut);
|
|
}
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CCifRWComponent::AddToMode(LPCSTR pszMode)
|
|
{
|
|
char szBuf[MAX_VALUE_LEN];
|
|
char szOneMode[MAX_ID_LENGTH];
|
|
LPSTR pszTmp;
|
|
UINT i = 0;
|
|
BOOL bFound = FALSE;
|
|
HRESULT hr = NOERROR;
|
|
|
|
if (SUCCEEDED(MyTranslateString(_pCif->GetCifPath(), _szID, MODES_KEY, szBuf, sizeof(szBuf))))
|
|
{
|
|
while(GetStringField(szBuf, i++, szOneMode, sizeof(szOneMode)))
|
|
{
|
|
if (lstrcmpi(szOneMode, pszMode) == 0)
|
|
{
|
|
// found it, no need to add
|
|
bFound = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
if (!bFound)
|
|
{
|
|
LPSTR pszTmp = szBuf + lstrlen(szBuf);
|
|
lstrcpy(pszTmp, ",");
|
|
pszTmp++;
|
|
lstrcpy(pszTmp, pszMode);
|
|
hr = WriteTokenizeString(_pCif->GetCifPath(), _szID, MODES_KEY, szBuf);
|
|
}
|
|
}
|
|
else
|
|
hr = WritePrivateProfileString(_szID, MODES_KEY, pszMode, _pCif->GetCifPath()) ? NOERROR : E_FAIL;
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CCifRWComponent::SetModes(LPCSTR pszMode)
|
|
{
|
|
return (WriteTokenizeString(_pCif->GetCifPath(), _szID, MODES_KEY, pszMode)?NOERROR:E_FAIL);
|
|
}
|
|
|
|
STDMETHODIMP CCifRWComponent::CopyComponent(LPCSTR pszCifFile)
|
|
{
|
|
LPSTR pszSec;
|
|
DWORD dwSize;
|
|
HRESULT hr = NOERROR;
|
|
|
|
dwSize = MAX_VALUE_LEN*4*4;
|
|
pszSec = (LPSTR)LocalAlloc(LPTR, dwSize); //allocate 4K buffer to read section
|
|
while(pszSec && GetPrivateProfileSection(_szID, pszSec, dwSize, pszCifFile)==(dwSize-2))
|
|
{
|
|
LocalFree(pszSec);
|
|
dwSize = dwSize*2;
|
|
pszSec = (LPSTR)LocalAlloc(LPTR, dwSize);
|
|
}
|
|
|
|
if (pszSec)
|
|
{
|
|
// first clean the Old section if there
|
|
WritePrivateProfileString(_szID, NULL, NULL, _pCif->GetCifPath());
|
|
// write out the copied section
|
|
WritePrivateProfileSection(_szID, pszSec, _pCif->GetCifPath());
|
|
|
|
LocalFree(pszSec);
|
|
}
|
|
else
|
|
hr = E_OUTOFMEMORY;
|
|
|
|
// need to check to see if we need to get strings out of the Strings section
|
|
|
|
CopyCifString(_szID, DISPLAYNAME_KEY, pszCifFile, _pCif->GetCifPath());
|
|
CopyCifString(_szID, DETAILS_KEY, pszCifFile, _pCif->GetCifPath());
|
|
CopyCifString(_szID, MODES_KEY, pszCifFile, _pCif->GetCifPath());
|
|
CopyCifString(_szID, LOCALE_KEY, pszCifFile, _pCif->GetCifPath());
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CCifRWComponent::AddToTreatAsOne(LPCSTR pszCompID)
|
|
{
|
|
char szBuf[MAX_VALUE_LEN];
|
|
char szOneID[MAX_ID_LENGTH];
|
|
LPSTR pszTmp;
|
|
UINT i = 0;
|
|
BOOL bFound = FALSE;
|
|
HRESULT hr = NOERROR;
|
|
|
|
if (SUCCEEDED(MyTranslateString(_pCif->GetCifPath(), _szID, TREATAS_KEY, szBuf, sizeof(szBuf))))
|
|
{
|
|
while(GetStringField(szBuf, i++, szOneID, sizeof(szOneID)))
|
|
{
|
|
if (lstrcmpi(szOneID, pszCompID) == 0)
|
|
{
|
|
// found it, no need to add
|
|
bFound = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
if (!bFound)
|
|
{
|
|
LPSTR pszTmp = szBuf + lstrlen(szBuf);
|
|
lstrcpy(pszTmp, ",");
|
|
pszTmp++;
|
|
lstrcpy(pszTmp, pszCompID);
|
|
hr = WriteTokenizeString(_pCif->GetCifPath(), _szID, TREATAS_KEY, szBuf);
|
|
}
|
|
}
|
|
else
|
|
hr = WritePrivateProfileString(_szID, TREATAS_KEY, pszCompID, _pCif->GetCifPath()) ? NOERROR : E_FAIL;
|
|
|
|
return hr;
|
|
}
|