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