|
|
//+--------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1994 - 1997.
//
// File: packages.cpp
//
// Contents: Methods on CComponentDataImpl related to package deployment
// and maintenence of the various index and cross-reference
// structures.
//
// Classes:
//
// Functions:
//
// History: 2-03-1998 stevebl Created
//
//---------------------------------------------------------------------------
// UNDONE - put in exception handling for low memory conditions
#include "precomp.hxx"
IMalloc * g_pIMalloc = NULL;
void CopyPlatformInfo(PLATFORMINFO * &ppiOut, PLATFORMINFO * & ppiIn) { if (NULL == ppiIn) { ppiOut = NULL; return; } ppiOut = (PLATFORMINFO *)OLEALLOC(sizeof(PLATFORMINFO)); memcpy(ppiOut, ppiIn, sizeof(PLATFORMINFO)); UINT n = ppiIn->cPlatforms; if (n) { ppiOut->prgPlatform = (CSPLATFORM*) OLEALLOC(sizeof(CSPLATFORM) * n); memcpy(ppiOut->prgPlatform, ppiIn->prgPlatform, sizeof(CSPLATFORM) * n); } n = ppiIn->cLocales; if (n) { ppiOut->prgLocale = (LCID *) OLEALLOC(sizeof(LCID) * n); memcpy(ppiOut->prgLocale, ppiIn->prgLocale, sizeof(LCID) * n); } }
void CopyActInfo(ACTIVATIONINFO * & paiOut, ACTIVATIONINFO * & paiIn) { if (NULL == paiIn) { paiOut = NULL; return; } paiOut = (ACTIVATIONINFO *) OLEALLOC(sizeof(ACTIVATIONINFO)); memcpy(paiOut, paiIn, sizeof(ACTIVATIONINFO)); UINT n = paiIn->cClasses; if (n) { paiOut->pClasses = (CLASSDETAIL *) OLEALLOC(sizeof(CLASSDETAIL) * n); memcpy(paiOut->pClasses, paiIn->pClasses, sizeof(CLASSDETAIL) * n); while (n--) { UINT n2 = paiIn->pClasses[n].cProgId; if (n2) { paiOut->pClasses[n].prgProgId = (LPOLESTR *) OLEALLOC(sizeof(LPOLESTR) * n2); while (n2--) { OLESAFE_COPYSTRING(paiOut->pClasses[n].prgProgId[n2], paiIn->pClasses[n].prgProgId[n2]); } } } } n = paiIn->cShellFileExt; if (n) { paiOut->prgPriority = (UINT *) OLEALLOC(sizeof(UINT) * n); memcpy(paiOut->prgPriority, paiIn->prgPriority, sizeof(UINT) * n); paiOut->prgShellFileExt = (LPOLESTR *) OLEALLOC(sizeof(LPOLESTR) * n); while (n--) { OLESAFE_COPYSTRING(paiOut->prgShellFileExt[n], paiIn->prgShellFileExt[n]); } } n = paiIn->cInterfaces; if (n) { paiOut->prgInterfaceId = (IID *) OLEALLOC(sizeof(IID) * n); memcpy(paiOut->prgInterfaceId, paiIn->prgInterfaceId, sizeof(IID) * n); } n = paiIn->cTypeLib; if (n) { paiOut->prgTlbId = (GUID *) OLEALLOC(sizeof(GUID) * n); memcpy(paiOut->prgTlbId, paiIn->prgTlbId, sizeof(GUID) * n); } }
void CopyInstallInfo(INSTALLINFO * & piiOut, INSTALLINFO * & piiIn) { if (NULL == piiIn) { piiOut = NULL; return; } piiOut = (INSTALLINFO *) OLEALLOC(sizeof(INSTALLINFO)); memcpy(piiOut, piiIn, sizeof(INSTALLINFO)); OLESAFE_COPYSTRING(piiOut->pszScriptPath, piiIn->pszScriptPath); OLESAFE_COPYSTRING(piiOut->pszSetupCommand, piiIn->pszSetupCommand); OLESAFE_COPYSTRING(piiOut->pszUrl, piiIn->pszUrl); if (piiIn->pClsid) { piiOut->pClsid = (GUID *) OLEALLOC(sizeof(GUID)); memcpy(piiOut->pClsid, piiIn->pClsid, sizeof(GUID)); } UINT n = piiIn->cUpgrades; if (n) { piiOut->prgUpgradeScript = (LPOLESTR *) OLEALLOC(sizeof(LPOLESTR) * n); piiOut->prgUpgradeFlag = (DWORD *) OLEALLOC(sizeof(DWORD) * n); memcpy(piiOut->prgUpgradeFlag, piiIn->prgUpgradeFlag, sizeof(DWORD) * n); while (n--) { OLESAFE_COPYSTRING(piiOut->prgUpgradeScript[n], piiIn->prgUpgradeScript[n]); } } }
void CopyPackageDetail(PACKAGEDETAIL * & ppdOut, PACKAGEDETAIL * & ppdIn) { if (NULL == ppdIn) { ppdOut = NULL; return; } ppdOut = new PACKAGEDETAIL; memcpy(ppdOut, ppdIn, sizeof(PACKAGEDETAIL)); OLESAFE_COPYSTRING(ppdOut->pszPackageName, ppdIn->pszPackageName); UINT n = ppdIn->cSources; if (n) { ppdOut->pszSourceList = (LPOLESTR *) OLEALLOC(sizeof(LPOLESTR) * n); while (n--) { OLESAFE_COPYSTRING(ppdOut->pszSourceList[n], ppdIn->pszSourceList[n]); } } n = ppdIn->cCategories; if (n) { ppdOut->rpCategory = (GUID *)OLEALLOC(sizeof(GUID) * n); memcpy(ppdOut->rpCategory, ppdIn->rpCategory, sizeof(GUID) * n); } CopyActInfo(ppdOut->pActInfo, ppdIn->pActInfo); CopyPlatformInfo(ppdOut->pPlatformInfo, ppdIn->pPlatformInfo); CopyInstallInfo(ppdOut->pInstallInfo, ppdIn->pInstallInfo); }
void FreeActInfo(ACTIVATIONINFO * & pai) { if (pai) { UINT n = pai->cClasses; while (n--) { UINT n2 = pai->pClasses[n].cProgId; while (n2--) { OLESAFE_DELETE(pai->pClasses[n].prgProgId[n2]); } OLESAFE_DELETE(pai->pClasses[n].prgProgId); } OLESAFE_DELETE(pai->pClasses); n = pai->cShellFileExt; while (n--) { OLESAFE_DELETE(pai->prgShellFileExt[n]); } OLESAFE_DELETE(pai->prgShellFileExt); OLESAFE_DELETE(pai->prgPriority); OLESAFE_DELETE(pai->prgInterfaceId); OLESAFE_DELETE(pai->prgTlbId); OLESAFE_DELETE(pai); } }
void FreePlatformInfo(PLATFORMINFO * &ppi) { if (ppi) { OLESAFE_DELETE(ppi->prgPlatform); OLESAFE_DELETE(ppi->prgLocale); OLESAFE_DELETE(ppi); } }
void FreeInstallInfo(INSTALLINFO * &pii) { if (pii) { OLESAFE_DELETE(pii->pszScriptPath); OLESAFE_DELETE(pii->pszSetupCommand); OLESAFE_DELETE(pii->pszUrl); OLESAFE_DELETE(pii->pClsid); UINT n = pii->cUpgrades; while (n--) { OLESAFE_DELETE(pii->prgUpgradeScript[n]); } if (pii->cUpgrades > 0) { OLESAFE_DELETE(pii->prgUpgradeScript); OLESAFE_DELETE(pii->prgUpgradeFlag); } OLESAFE_DELETE(pii); } }
void FreePackageDetail(PACKAGEDETAIL * & ppd) { if (ppd) { OLESAFE_DELETE(ppd->pszPackageName); UINT n = ppd->cSources; while (n--) { OLESAFE_DELETE(ppd->pszSourceList[n]); } OLESAFE_DELETE(ppd->rpCategory); FreeActInfo(ppd->pActInfo); FreePlatformInfo(ppd->pPlatformInfo); FreeInstallInfo(ppd->pInstallInfo); delete ppd; ppd = NULL; } }
//+--------------------------------------------------------------------------
//
// Member: CComponentDataImpl::GetUniquePackageName
//
// Synopsis: Returns a unique package name.
//
// Arguments: [sz] - [in] the name of the package
// [out] the new name, guaranteed unique on this cs
//
// History: 1-23-1998 stevebl Created
//
// Notes: First the input name is checked for uniqueness. If it is
// already unique it is returned unchanged. If it is not
// unique then a new name is formed by adding " (2)" to the end
// of the string, then " (3)" and " (4)" and so on until a
// unique name is found.
//
//---------------------------------------------------------------------------
void CComponentDataImpl::GetUniquePackageName(CString &sz) { std::map<long, APP_DATA>::iterator i; std::set<CString> sNames; int cch = sz.GetLength(); for (i=m_AppData.begin(); i != m_AppData.end(); i++) { // As an optimization, I'm only going to add names that might match
// this one to the set.
LPOLESTR szName = i->second.pDetails->pszPackageName; if (0 == wcsncmp(sz, szName, cch)) sNames.insert(szName); } CString szRoot = sz; int index = 2; // start trying new names by adding (2) to the end
// now check for a match
do { if (sNames.end() == sNames.find(sz)) { // we are unique
return; } // try a different name
sz.Format(L"%s (%i)", (LPCTSTR)szRoot, index++); } while (TRUE); }
//+--------------------------------------------------------------------------
//
// Member: CComponentDataImpl::AddMSIPackage
//
// Synopsis: Add's one or more packages to the class store and adds the
// appropriate entries to the result pane.
//
// Arguments: [szPackagePath] - Full path to the Darwin package.
// [lpFileTitle] - file title from the open file dialog (used
// for UI)
//
// Returns: S_OK - succeeded
// E_FAIL - benign failure (probably a cancellation or something)
// other - significant failure
//
// History: 2-03-1998 stevebl Created
//
//---------------------------------------------------------------------------
HRESULT CComponentDataImpl::AddMSIPackage(LPCOLESTR szPackagePath, LPCOLESTR lpFileTitle) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); HRESULT hr = E_FAIL; if (m_pIClassAdmin) { ASSERT(m_pConsole); { BOOL fShowPropertySheet = FALSE; BOOL fShowUpgradeDialog = FALSE; GUID guid; PACKAGEDETAIL *ppd = new PACKAGEDETAIL; memset(ppd, 0, sizeof(PACKAGEDETAIL)); INSTALLINFO * pii = (INSTALLINFO *) OLEALLOC(sizeof(INSTALLINFO)); memset(pii, 0, sizeof(INSTALLINFO)); PLATFORMINFO * ppi = (PLATFORMINFO *) OLEALLOC(sizeof(PLATFORMINFO)); memset(ppi, 0, sizeof(PLATFORMINFO)); ACTIVATIONINFO * pai = (ACTIVATIONINFO *) OLEALLOC(sizeof(ACTIVATIONINFO)); memset(pai, 0, sizeof(ACTIVATIONINFO)); ppd->pActInfo = pai; ppd->pPlatformInfo = ppi; ppd->pInstallInfo = pii; // If appropriate, use the deployment wizard to set the
// deployment type, otherwise use the default settings
switch (m_ToolDefaults.NPBehavior) { case NP_WIZARD: { CDeployApp dlgDeployApp; if (IDCANCEL == dlgDeployApp.DoModal()) { FreePackageDetail(ppd); return E_FAIL; } switch (dlgDeployApp.m_iDeployment) { case 0: // upgrade
fShowUpgradeDialog = TRUE; pii->dwActFlags = ACTFLG_Published | ACTFLG_UserInstall; break; case 1: //published
pii->dwActFlags = ACTFLG_Published | ACTFLG_UserInstall | ACTFLG_OnDemandInstall; break; case 2: // assigned
pii->dwActFlags = ACTFLG_Assigned | ACTFLG_OnDemandInstall; break; case 4: // custom
fShowPropertySheet = TRUE; // fall through to disabled
case 3: // disabled
default: pii->dwActFlags = ACTFLG_Published; break; } } break; case NP_PUBLISHED: pii->dwActFlags = ACTFLG_Published | ACTFLG_UserInstall; if (m_ToolDefaults.fAutoInstall) { pii->dwActFlags |= ACTFLG_OnDemandInstall; } break; case NP_ASSIGNED: pii->dwActFlags = ACTFLG_Assigned | ACTFLG_OnDemandInstall; break; case NP_PROPPAGE: fShowPropertySheet = TRUE; // fall through to disabled
case NP_DISABLED: default: pii->dwActFlags = ACTFLG_Published; break; } pii->PathType = DrwFilePath; pii->InstallUiLevel = m_ToolDefaults.UILevel; std::set<LCID> sLocales; // Use MsiSummaryInfoGetProperty to get platform and locale info.
{ MSIHANDLE hSummaryInfo; UINT msiReturn = MsiGetSummaryInformation(0, szPackagePath, 0, &hSummaryInfo); if (ERROR_SUCCESS == msiReturn) { TCHAR szBuffer[256]; DWORD dwSize = 256; msiReturn = MsiSummaryInfoGetProperty(hSummaryInfo, 7, // PID_TEMPLATE
NULL, NULL, NULL, szBuffer, &dwSize); if (ERROR_SUCCESS == msiReturn) { // break out the locale and platform properties
CString szLocales = szBuffer; CString szPlatforms = szLocales.SpanExcluding(L";"); szLocales = szLocales.Mid(szPlatforms.GetLength()+1); CString szTemp; std::set<DWORD> sPlatforms; while (szPlatforms.GetLength()) { szTemp = szPlatforms.SpanExcluding(L","); if (0 == szTemp.CompareNoCase(L"alpha")) { sPlatforms.insert(PROCESSOR_ARCHITECTURE_ALPHA); } else if (0 == szTemp.CompareNoCase(L"intel")) { sPlatforms.insert(PROCESSOR_ARCHITECTURE_INTEL); } szPlatforms = szPlatforms.Mid(szTemp.GetLength()+1); } while (szLocales.GetLength()) { szTemp = szLocales.SpanExcluding(L","); LCID lcid; swscanf(szTemp, L"%i", &lcid); sLocales.insert(lcid); szLocales = szLocales.Mid(szTemp.GetLength()+1); } if (0 == sLocales.size() || 0 == sPlatforms.size()) { // either not enough locales or platforms
FreePackageDetail(ppd); return E_FAIL; // need better error message?
} ppi->cPlatforms = sPlatforms.size(); ppi->prgPlatform = (CSPLATFORM *) OLEALLOC(sizeof(CSPLATFORM) * (ppi->cPlatforms));; std::set<DWORD>::iterator iPlatform; INT n = 0; for (iPlatform = sPlatforms.begin(); iPlatform != sPlatforms.end(); iPlatform++, n++) { ppi->prgPlatform[n].dwPlatformId = VER_PLATFORM_WIN32_NT; ppi->prgPlatform[n].dwVersionHi = 5; ppi->prgPlatform[n].dwVersionLo = 0; ppi->prgPlatform[n].dwProcessorArch = *iPlatform; } } MsiCloseHandle(hSummaryInfo); } if (ERROR_SUCCESS != msiReturn) { FreePackageDetail(ppd); return HRESULT_FROM_WIN32(msiReturn); } } ppi->cLocales = 1; ppi->prgLocale = (LCID *) OLEALLOC(sizeof(LCID)); ppd->cSources = 1; ppd->pszSourceList = (LPOLESTR *) OLEALLOC(sizeof(LPOLESTR)); OLESAFE_COPYSTRING(ppd->pszSourceList[0], szPackagePath); // UNDONE - check to see if we can detect any upgrade relationships
if (fShowUpgradeDialog) { CUpgrades dlgUpgrade; dlgUpgrade.m_pAppData = &m_AppData; if (IDCANCEL == dlgUpgrade.DoModal()) { FreePackageDetail(ppd); return E_FAIL; } UINT n = dlgUpgrade.m_UpgradeList.size(); if (n) { pii->cUpgrades = n; pii->prgUpgradeScript = (LPOLESTR *) OLEALLOC(sizeof(LPOLESTR) * n); pii->prgUpgradeFlag = (DWORD *) OLEALLOC(sizeof(DWORD) * n); std::map<long, BOOL>::iterator i = dlgUpgrade.m_UpgradeList.begin(); while (n--) { if (i->second) { pii->prgUpgradeFlag[n] = UPGFLG_Uninstall; } else { pii->prgUpgradeFlag[n] = UPGFLG_NoUninstall; } LPOLESTR sz = m_AppData[i->first].pDetails->pInstallInfo->pszScriptPath; OLESAFE_COPYSTRING(pii->prgUpgradeScript[n], sz); i++; } } }
// Put up the locale dialog and allow the user to remove locales
// from the list if he so desires.
if (1 < sLocales.size()) { CLcidPick dlgLcidPick; dlgLcidPick.m_psLocales = &sLocales; int iReturn = dlgLcidPick.DoModal(); if (IDCANCEL == iReturn || 0 == sLocales.size()) { FreePackageDetail(ppd); return E_FAIL; } }
// For each locale left in the list, publish a package and add
// it to the class store.
int nLocales = sLocales.size(); std::set<LCID>::iterator iLocale; for (iLocale = sLocales.begin(); iLocale != sLocales.end(); iLocale++) { ppi->prgLocale[0] = *iLocale;
// set the script path
hr = CoCreateGuid(&guid); if (FAILED(hr)) { FreePackageDetail(ppd); return hr; } OLECHAR sz [256]; StringFromGUID2(guid, sz, 256); CString szScriptPath = m_szScriptRoot; szScriptPath += L"\\"; szScriptPath += sz; szScriptPath += L".aas"; OLESAFE_DELETE(pii->pszScriptPath); OLESAFE_COPYSTRING(pii->pszScriptPath, szScriptPath);
// set the package name
{ MSIHANDLE hProduct; UINT msiReturn = MsiOpenPackage(szPackagePath, &hProduct); if (ERROR_SUCCESS == msiReturn) { DWORD dw = 256; OLECHAR szBuffer[256]; msiReturn = MsiGetProductProperty(hProduct, INSTALLPROPERTY_PRODUCTNAME, szBuffer, &dw); if (ERROR_SUCCESS == msiReturn) { CString sz = szBuffer; // If there is more than one locale in the
// locale list, then append the locale to the
// name to help distinguish it.
if (1 < nLocales) { sz += L" ("; GetLocaleInfo(ppi->prgLocale[0], LOCALE_SLANGUAGE, szBuffer, 256); sz += szBuffer; GetLocaleInfo(ppi->prgLocale[0], LOCALE_SCOUNTRY, szBuffer, 256); sz += _T(" - "); sz += szBuffer; sz += L")"; } // make sure the name is unique
GetUniquePackageName(sz); OLESAFE_DELETE(ppd->pszPackageName); OLESAFE_COPYSTRING(ppd->pszPackageName, sz); } MsiCloseHandle(hProduct); } if (ERROR_SUCCESS != msiReturn) { FreePackageDetail(ppd); return HRESULT_FROM_WIN32(msiReturn); } } HWND hwnd; m_pConsole->GetMainWindow(&hwnd); hr = BuildScriptAndGetActInfo(m_szGPTRoot, *ppd); if (SUCCEEDED(hr)) { hr = PrepareExtensions(*ppd); if (SUCCEEDED(hr)) { // put the script in the class store
hr = m_pIClassAdmin->AddPackage(ppd->pszPackageName, ppd); } } if (S_OK != hr) { TCHAR szBuffer[256]; ::LoadString(ghInstance, IDS_ADDFAILED, szBuffer, 256); #if DBG
TCHAR szDebugBuffer[256]; DWORD dw = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, hr, 0, szDebugBuffer, sizeof(szDebugBuffer) / sizeof(szDebugBuffer[0]), NULL); if (0 == dw) { wsprintf(szDebugBuffer, TEXT("(HRESULT: 0x%lX)"), hr); } wcscat(szBuffer, szDebugBuffer); #endif
m_pConsole->MessageBox(szBuffer, lpFileTitle, MB_OK, NULL); FreePackageDetail(ppd); return hr; } else { APP_DATA data; CopyPackageDetail(data.pDetails, ppd);
data.InitializeExtraInfo();
m_lLastAllocated++; m_AppData[m_lLastAllocated] = data;
RESULTDATAITEM resultItem;
resultItem.mask = RDI_STR | RDI_IMAGE | RDI_PARAM; resultItem.str = MMC_CALLBACK; resultItem.nImage = data.GetImageIndex(this); // BUGBUG - need to make sure that m_lLastAllocated
// hasn't already been used!
resultItem.lParam = m_lLastAllocated; hr = m_pSnapin->m_pResult->InsertItem(&resultItem); if (SUCCEEDED(hr)) { #if UGLY_SUBDIRECTORY_HACK
if (0 != (data.pDetails->pInstallInfo->dwActFlags & ACTFLG_Assigned)) { CString sz = m_szGPTRoot; sz += L"\\"; sz += data.pDetails->pInstallInfo->pszScriptPath; // copy to subdirectories
CString szRoot; CString szFile; int i = sz.ReverseFind(L'\\'); szRoot = sz.Left(i); szFile = sz.Mid(i+1); CString szTemp; for (i = data.pDetails->pPlatformInfo->cPlatforms; i--;) { if (PROCESSOR_ARCHITECTURE_INTEL == data.pDetails->pPlatformInfo->prgPlatform[i].dwProcessorArch) { szTemp = szRoot; szTemp += L"\\assigned\\x86\\"; szTemp += szFile; CopyFile(sz, szTemp, FALSE); } if (PROCESSOR_ARCHITECTURE_ALPHA == data.pDetails->pPlatformInfo->prgPlatform[i].dwProcessorArch) { szTemp = szRoot; szTemp += L"\\assigned\\alpha\\"; szTemp += szFile; CopyFile(sz, szTemp, FALSE); } } } #endif
m_AppData[m_lLastAllocated].itemID = resultItem.itemID; InsertExtensionEntry(m_lLastAllocated, m_AppData[m_lLastAllocated]); if (m_pFileExt) { m_pFileExt->SendMessage(WM_USER_REFRESH, 0, 0); } InsertUpgradeEntry(m_lLastAllocated, m_AppData[m_lLastAllocated]); m_ScriptIndex[data.pDetails->pInstallInfo->pszScriptPath] = m_lLastAllocated; // if this is an upgrade, set icons for upgraded apps to
// the proper icon.
UINT n = data.pDetails->pInstallInfo->cUpgrades; while (n--) { std::map<CString, long>::iterator i = m_ScriptIndex.find(data.pDetails->pInstallInfo->prgUpgradeScript[n]); if (i != m_ScriptIndex.end()) { RESULTDATAITEM rd; memset(&rd, 0, sizeof(rd)); rd.mask = RDI_IMAGE; rd.itemID = m_AppData[i->second].itemID; rd.nImage = IMG_UPGRADE; m_pSnapin->m_pResult->SetItem(&rd); } } m_pSnapin->m_pResult->Sort(0, 0, -1); } } } FreePackageDetail(ppd); } } return hr; }
//+--------------------------------------------------------------------------
//
// Member: CComponentDataImpl::RemovePackage
//
// Synopsis: Removes a package from the class store and the result pane.
//
// Arguments: [pDataObject] - data object for this result pane item
//
// Returns: S_OK - success
//
// History: 2-03-1998 stevebl Created
//
// Notes: bAssigned is used
//
//---------------------------------------------------------------------------
HRESULT CComponentDataImpl::RemovePackage(long cookie) { BOOL fAssigned; HRESULT hr = E_FAIL; // put up an hourglass (this could take a while)
CHourglass hourglass; APP_DATA & data = m_AppData[cookie];
// We need to make sure it gets removed from
// the GPT before we delete it from the class store.
CString sz = m_szGPTRoot; sz += L"\\"; sz += data.pDetails->pInstallInfo->pszScriptPath; DeleteFile(sz); #if UGLY_SUBDIRECTORY_HACK
{ // delete from subdirectories
CString szRoot; CString szFile; int i = sz.ReverseFind(L'\\'); szRoot = sz.Left(i); szFile = sz.Mid(i+1); CString szTemp; szTemp = szRoot; szTemp += L"\\assigned\\x86\\"; szTemp += szFile; DeleteFile(szTemp); szTemp = szRoot; szTemp += L"\\assigned\\alpha\\"; szTemp += szFile; DeleteFile(szTemp); } #endif
if (0 != (data.pDetails->pInstallInfo->dwActFlags & ACTFLG_Assigned)) { fAssigned = TRUE; } else { fAssigned = FALSE; } hr = m_pIClassAdmin->RemovePackage((LPOLESTR)((LPCOLESTR)(data.pDetails->pszPackageName)));
if (SUCCEEDED(hr)) { hr = m_pSnapin->m_pResult->DeleteItem(data.itemID, 0); if (SUCCEEDED(hr)) { // remove its entries in the extension table
RemoveExtensionEntry(cookie, data); if (m_pFileExt) { m_pFileExt->SendMessage(WM_USER_REFRESH, 0, 0); } RemoveUpgradeEntry(cookie, data); m_ScriptIndex.erase(data.pDetails->pInstallInfo->pszScriptPath); // If this thing upgraded other apps, make sure that
// they get the proper icons.
UINT n = data.pDetails->pInstallInfo->cUpgrades; while (n--) { std::map<CString, long>::iterator i = m_ScriptIndex.find(data.pDetails->pInstallInfo->prgUpgradeScript[n]); if (i != m_ScriptIndex.end()) { RESULTDATAITEM rd; memset(&rd, 0, sizeof(rd)); rd.mask = RDI_IMAGE; rd.itemID = m_AppData[i->second].itemID; rd.nImage = m_AppData[i->second].GetImageIndex(this); m_pSnapin->m_pResult->SetItem(&rd); } } // If other apps were upgrading this app, do the same.
std::set<long>::iterator i; for (i = data.sUpgrades.begin(); i != data.sUpgrades.end(); i++) { RESULTDATAITEM rd; memset(&rd, 0, sizeof(rd)); rd.mask = RDI_IMAGE; rd.itemID = m_AppData[*i].itemID; rd.nImage = m_AppData[*i].GetImageIndex(this); m_pSnapin->m_pResult->SetItem(&rd); } FreePackageDetail(data.pDetails); m_AppData.erase(cookie); m_pSnapin->m_pResult->Sort(0, 0, -1); // Notify clients of change
if (m_pIGPEInformation && fAssigned) { m_pIGPEInformation->PolicyChanged(); } } } return hr; }
//+--------------------------------------------------------------------------
//
// Member: CComponentDataImpl::PopulateUpgradeLists
//
// Synopsis: Walks the list of apps, making sure that all the upgrade
// tables are complete.
//
// Arguments: none
//
// Returns:
//
// History: 2-02-1998 stevebl Created
//
//---------------------------------------------------------------------------
HRESULT CComponentDataImpl::PopulateUpgradeLists() { HRESULT hr = S_OK; // For each app in the list, insert an entry in the upgrade tables of
// the apps it upgrades.
std::map <long, APP_DATA>::iterator iAppData; for (iAppData=m_AppData.begin(); iAppData != m_AppData.end(); iAppData++) { hr = InsertUpgradeEntry(iAppData->first, iAppData->second); if (FAILED(hr)) { return hr; } } return hr; }
//+--------------------------------------------------------------------------
//
// Member: CComponentDataImpl::InsertUpgradeEntry
//
// Synopsis: For every app that this app upgrades, place an entry in its
// upgrades set so that it points back to this one.
//
// Arguments: [cookie] -
// [data] -
//
// Returns:
//
// History: 2-02-1998 stevebl Created
//
// Notes: Needs to be able to deal with scripts that might not be in
// this OU.
//
//---------------------------------------------------------------------------
HRESULT CComponentDataImpl::InsertUpgradeEntry(long cookie, APP_DATA & data) { UINT n = data.pDetails->pInstallInfo->cUpgrades; while (n--) { std::map<CString,long>::iterator i = m_ScriptIndex.find(data.pDetails->pInstallInfo->prgUpgradeScript[n]); if (m_ScriptIndex.end() != i) { m_AppData[i->second].sUpgrades.insert(cookie); } } return S_OK; }
//+--------------------------------------------------------------------------
//
// Member: CComponentDataImpl::RemoveUpgradeEntry
//
// Synopsis: For every app that this app upgraded, remove the entry from
// its upgrades set.
//
// Arguments: [cookie] -
// [data] -
//
// Returns:
//
// History: 2-02-1998 stevebl Created
//
// Notes: Needs to be able to deal with scripts that might not be in
// this OU.
//
//---------------------------------------------------------------------------
HRESULT CComponentDataImpl::RemoveUpgradeEntry(long cookie, APP_DATA & data) { UINT n = data.pDetails->pInstallInfo->cUpgrades; while (n--) { std::map<CString,long>::iterator i = m_ScriptIndex.find(data.pDetails->pInstallInfo->prgUpgradeScript[n]); if (m_ScriptIndex.end() != i) { m_AppData[i->second].sUpgrades.erase(cookie); } } return S_OK; }
//+--------------------------------------------------------------------------
//
// Member: CComponentDataImpl::PopulateExtensions
//
// Synopsis: Builds the file extension table from the list of applications.
//
// Arguments: (none)
//
// Returns:
//
// History: 1-29-1998 stevebl Created
//
//---------------------------------------------------------------------------
HRESULT CComponentDataImpl::PopulateExtensions() { HRESULT hr = S_OK; // first erase the old extension list
m_Extensions.erase(m_Extensions.begin(), m_Extensions.end()); // now add each app's extensions to the table
std::map <long, APP_DATA>::iterator iAppData; for (iAppData=m_AppData.begin(); iAppData != m_AppData.end(); iAppData++) { hr = InsertExtensionEntry(iAppData->first, iAppData->second); if (FAILED(hr)) { return hr; } } if (m_pFileExt) { m_pFileExt->SendMessage(WM_USER_REFRESH, 0, 0); } return hr; }
//+--------------------------------------------------------------------------
//
// Member: CComponentDataImpl::InsertExtensionEntry
//
// Synopsis: Adds a single entry to the extension tables.
//
// Arguments: [cookie] -
// [data] -
//
// Returns:
//
// History: 1-29-1998 stevebl Created
//
//---------------------------------------------------------------------------
HRESULT CComponentDataImpl::InsertExtensionEntry(long cookie, APP_DATA & data) { UINT n = data.pDetails->pActInfo->cShellFileExt; while (n--) { m_Extensions[data.pDetails->pActInfo->prgShellFileExt[n]].insert(cookie); } return S_OK; }
//+--------------------------------------------------------------------------
//
// Member: CComponentDataImpl::RemoveExtensionEntry
//
// Synopsis: Removes ane entry from the extension tables.
//
// Arguments: [cookie] -
// [data] -
//
// Returns:
//
// History: 1-29-1998 stevebl Created
//
//---------------------------------------------------------------------------
HRESULT CComponentDataImpl::RemoveExtensionEntry(long cookie, APP_DATA & data) { UINT n = data.pDetails->pActInfo->cShellFileExt; while (n--) { m_Extensions[data.pDetails->pActInfo->prgShellFileExt[n]].erase(cookie); if (m_Extensions[data.pDetails->pActInfo->prgShellFileExt[n]].empty()) { m_Extensions.erase(data.pDetails->pActInfo->prgShellFileExt[n]); } } return S_OK; }
//+--------------------------------------------------------------------------
//
// Member: CComponentDataImpl::PrepareExtensions
//
// Synopsis: Sets extension priorities so that this data can be inserted
// into the extension list with the proper priority.
//
// Arguments: [pd] -
//
// Returns:
//
// Modifies:
//
// Derivation:
//
// History: 1-29-1998 stevebl Created
//
//---------------------------------------------------------------------------
HRESULT CComponentDataImpl::PrepareExtensions(PACKAGEDETAIL &pd) { UINT n = pd.pActInfo->cShellFileExt; while (n--) { // For each extension that is going to be added, we need to assign
// it a priority that is one larger than the largest priority
// already added.
// NOTE: The odds of this number rolling over to 0 are so
// unlikely that it would be pointless to check for it. In any case
// the results of such a bug would be easy for the admin to remedy
// via the file extension priority dialog.
pd.pActInfo->prgPriority[n] = 0; EXTLIST::iterator i; CString sz = pd.pActInfo->prgShellFileExt[n]; for (i= m_Extensions[sz].begin(); i != m_Extensions[sz].end(); i++) { // look for the entry that matches this file extension
APP_DATA & data = m_AppData[*i]; UINT n2 = data.pDetails->pActInfo->cShellFileExt; while (n2--) { if (0 == sz.CompareNoCase(data.pDetails->pActInfo->prgShellFileExt[n2])) { break; } } if (data.pDetails->pActInfo->prgPriority[n2] >= pd.pActInfo->prgPriority[n]) { pd.pActInfo->prgPriority[n] = data.pDetails->pActInfo->prgPriority[n2] + 1; } } } return S_OK; }
//+--------------------------------------------------------------------------
//
// Member: CComponentDataImpl::ChangePackageState
//
// Synopsis: Changes the state of a package and puts up advisory message
// boxes informing the admin about the effects of the change.
//
// Arguments: [data] - entry to change
// [dwNewState] - new state
//
// History: 2-03-1998 stevebl Created
//
//---------------------------------------------------------------------------
STDMETHODIMP CComponentDataImpl::ChangePackageState(APP_DATA &data, DWORD dwNewState, BOOL fShowUI) { HRESULT hr = S_OK;
// first detect what's changed
DWORD dwOldState = data.pDetails->pInstallInfo->dwActFlags; DWORD dwChange = dwOldState ^ dwNewState;
if (dwChange) { // something changed
if (fShowUI) { // Build a notification message
CString szNotify = L""; WCHAR szBuffer [256];
BOOL fAskAboutAutoInstall = FALSE;
// changes we care about:
//
// Assigned flag changed:
// UserInstall flag changed:
// OnDemandInstall flag changed: (We only care about this if we
// aren't going to ask)
if (dwChange & (ACTFLG_Assigned | ACTFLG_Published)) { if (dwNewState & ACTFLG_Assigned) { ::LoadString(ghInstance, IDS_TO_ASSIGNED, szBuffer, 256); } else { ::LoadString(ghInstance, IDS_TO_PUBLISHED, szBuffer, 256); if (dwNewState & (ACTFLG_UserInstall | ACTFLG_OnDemandInstall)) fAskAboutAutoInstall = TRUE; } szNotify += szBuffer; }
if (dwChange & ACTFLG_UserInstall) { if (dwNewState & ACTFLG_UserInstall) { ::LoadString(ghInstance, IDS_USERINSTALL_ON, szBuffer, 256);
// This check takes care of making sure we ask about
// AutoInstall when moving from the Disabled to the
// Published state.
if ((!(dwNewState & ACTFLG_Assigned)) && !(dwOldState & ACTFLG_OnDemandInstall)) fAskAboutAutoInstall = TRUE; } else { ::LoadString(ghInstance, IDS_USERINSTALL_OFF, szBuffer, 256); } szNotify += szBuffer; }
if (fAskAboutAutoInstall) { ::LoadString(ghInstance, IDS_ASK_AUTOINSTALL, szBuffer, 256); szNotify += szBuffer; int iReturn = ::MessageBox(NULL, szNotify, data.pDetails->pszPackageName, MB_YESNOCANCEL); if (IDCANCEL == iReturn) { return E_ABORT; }
if (IDYES == iReturn) dwNewState |= ACTFLG_OnDemandInstall; else dwNewState &= ~ACTFLG_OnDemandInstall; } else { if ((!(dwNewState & ACTFLG_Assigned)) && (dwChange & ACTFLG_OnDemandInstall)) { if (dwNewState & ACTFLG_OnDemandInstall) { ::LoadString(ghInstance, IDS_AUTOINSTALL_ON, szBuffer, 256); } else { ::LoadString(ghInstance, IDS_AUTOINSTALL_OFF, szBuffer, 256); } szNotify += szBuffer; }
int iReturn = ::MessageBox(NULL, szNotify, data.pDetails->pszPackageName, MB_OKCANCEL);
if (IDCANCEL == iReturn) { return E_ABORT; } } } // commit changes
hr = m_pIClassAdmin->ChangePackageProperties(data.pDetails->pszPackageName, NULL, &dwNewState, NULL, NULL, NULL); if (SUCCEEDED(hr)) { data.pDetails->pInstallInfo->dwActFlags = dwNewState; RESULTDATAITEM rd; memset(&rd, 0, sizeof(rd)); rd.mask = RDI_IMAGE; rd.itemID = data.itemID; rd.nImage = data.GetImageIndex(this); m_pSnapin->m_pResult->SetItem(&rd); m_pSnapin->m_pResult->Sort(0, 0, -1); data.NotifyChange(); #if UGLY_SUBDIRECTORY_HACK
{ CString sz = m_szGPTRoot; sz += L"\\"; sz += data.pDetails->pInstallInfo->pszScriptPath; // copy to subdirectories
CString szRoot; CString szFile; int i = sz.ReverseFind(L'\\'); szRoot = sz.Left(i); szFile = sz.Mid(i+1); CString szTemp; if (0 != (data.pDetails->pInstallInfo->dwActFlags & ACTFLG_Assigned)) { for (i = data.pDetails->pPlatformInfo->cPlatforms; i--;) { if (PROCESSOR_ARCHITECTURE_INTEL == data.pDetails->pPlatformInfo->prgPlatform[i].dwProcessorArch) { szTemp = szRoot; szTemp += L"\\assigned\\x86\\"; szTemp += szFile; CopyFile(sz, szTemp, FALSE); } if (PROCESSOR_ARCHITECTURE_ALPHA == data.pDetails->pPlatformInfo->prgPlatform[i].dwProcessorArch) { szTemp = szRoot; szTemp += L"\\assigned\\alpha\\"; szTemp += szFile; CopyFile(sz, szTemp, FALSE); } } } else { szTemp = szRoot; szTemp += L"\\assigned\\x86\\"; szTemp += szFile; DeleteFile(szTemp); szTemp = szRoot; szTemp += L"\\assigned\\alpha\\"; szTemp += szFile; DeleteFile(szTemp); } } #endif
} }
return hr; }
|