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

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;
}