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

3245 lines
120 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1994 - 1998.
  5. //
  6. // File: packages.cpp
  7. //
  8. // Contents: Methods on CScopePane related to package deployment
  9. // and maintenence of the various index and cross-reference
  10. // structures.
  11. //
  12. // Classes:
  13. //
  14. // Functions: CopyPackageDetail
  15. // FreePackageDetail
  16. // GetMsiProperty
  17. //
  18. // History: 2-03-1998 stevebl Created
  19. // 3-25-1998 stevebl Added GetMsiProperty
  20. // 5-20-1998 RahulTh - Added DetectUpgrades for automatic upgrade
  21. // detection
  22. // - Added GetCapitalizedExt
  23. //
  24. //---------------------------------------------------------------------------
  25. // UNDONE - put in exception handling for low memory conditions
  26. #include "precomp.hxx"
  27. // uncomment this line to get the old behavior of putting up an upgrade
  28. // dialog for auto-detected upgrades
  29. //#define SHOWDETECTEDUPGRADEDIALOG
  30. //IMalloc * g_pIMalloc = NULL;
  31. BOOL IsNullGUID (GUID *pguid)
  32. {
  33. return ( (pguid->Data1 == 0) &&
  34. (pguid->Data2 == 0) &&
  35. (pguid->Data3 == 0) &&
  36. (pguid->Data4[0] == 0) &&
  37. (pguid->Data4[1] == 0) &&
  38. (pguid->Data4[2] == 0) &&
  39. (pguid->Data4[3] == 0) &&
  40. (pguid->Data4[4] == 0) &&
  41. (pguid->Data4[5] == 0) &&
  42. (pguid->Data4[6] == 0) &&
  43. (pguid->Data4[7] == 0) );
  44. }
  45. void FreePlatformInfo(PLATFORMINFO * &ppiOut)
  46. {
  47. if (ppiOut)
  48. {
  49. OLESAFE_DELETE(ppiOut->prgPlatform);
  50. OLESAFE_DELETE(ppiOut->prgLocale);
  51. OLESAFE_DELETE(ppiOut);
  52. }
  53. }
  54. HRESULT CopyPlatformInfo(PLATFORMINFO * &ppiOut, PLATFORMINFO * & ppiIn)
  55. {
  56. if (NULL == ppiIn)
  57. {
  58. ppiOut = NULL;
  59. return S_OK;
  60. }
  61. UINT n;
  62. ppiOut = (PLATFORMINFO *)OLEALLOC(sizeof(PLATFORMINFO));
  63. if (!ppiOut)
  64. {
  65. goto out_of_memory;
  66. }
  67. memcpy(ppiOut, ppiIn, sizeof(PLATFORMINFO));
  68. ppiOut->prgPlatform = NULL;
  69. ppiOut->prgLocale = NULL;
  70. n = ppiIn->cPlatforms;
  71. if (n)
  72. {
  73. ppiOut->prgPlatform = (CSPLATFORM*) OLEALLOC(sizeof(CSPLATFORM) * n);
  74. if (!ppiOut->prgPlatform)
  75. {
  76. goto out_of_memory;
  77. }
  78. memcpy(ppiOut->prgPlatform, ppiIn->prgPlatform, sizeof(CSPLATFORM) * n);
  79. }
  80. n = ppiIn->cLocales;
  81. if (n)
  82. {
  83. ppiOut->prgLocale = (LCID *) OLEALLOC(sizeof(LCID) * n);
  84. if (!ppiOut->prgLocale)
  85. {
  86. goto out_of_memory;
  87. }
  88. memcpy(ppiOut->prgLocale, ppiIn->prgLocale, sizeof(LCID) * n);
  89. }
  90. return S_OK;
  91. out_of_memory:
  92. FreePlatformInfo(ppiOut);
  93. return E_OUTOFMEMORY;
  94. }
  95. void FreeActInfo(ACTIVATIONINFO * &paiOut)
  96. {
  97. if (paiOut)
  98. {
  99. if (paiOut->pClasses)
  100. {
  101. UINT n = paiOut->cClasses;
  102. while (n--)
  103. {
  104. OLESAFE_DELETE(paiOut->pClasses[n].prgProgId);
  105. }
  106. OLESAFE_DELETE(paiOut->pClasses);
  107. }
  108. OLESAFE_DELETE(paiOut->prgInterfaceId);
  109. OLESAFE_DELETE(paiOut->prgPriority);
  110. if (paiOut->prgShellFileExt)
  111. {
  112. UINT n = paiOut->cShellFileExt;
  113. while (n--)
  114. {
  115. OLESAFE_DELETE(paiOut->prgShellFileExt[n])
  116. }
  117. OLESAFE_DELETE(paiOut->prgShellFileExt);
  118. }
  119. OLESAFE_DELETE(paiOut->prgTlbId);
  120. OLESAFE_DELETE(paiOut);
  121. }
  122. }
  123. HRESULT CopyActInfo(ACTIVATIONINFO * & paiOut, ACTIVATIONINFO * & paiIn)
  124. {
  125. if (NULL == paiIn)
  126. {
  127. paiOut = NULL;
  128. return S_OK;
  129. }
  130. UINT n;
  131. paiOut = (ACTIVATIONINFO *) OLEALLOC(sizeof(ACTIVATIONINFO));
  132. if (!paiOut)
  133. {
  134. goto out_of_memory;
  135. }
  136. memcpy(paiOut, paiIn, sizeof(ACTIVATIONINFO));
  137. paiOut->prgInterfaceId = NULL;
  138. paiOut->prgPriority = NULL;
  139. paiOut->prgShellFileExt = NULL;
  140. paiOut->prgTlbId = NULL;
  141. paiOut->pClasses = NULL;
  142. n = paiIn->cClasses;
  143. paiOut->bHasClasses = paiIn->bHasClasses;
  144. if (n)
  145. {
  146. paiOut->pClasses = (CLASSDETAIL *) OLEALLOC(sizeof(CLASSDETAIL) * n);
  147. if (!paiOut->pClasses)
  148. {
  149. goto out_of_memory;
  150. }
  151. memcpy(paiOut->pClasses, paiIn->pClasses, sizeof(CLASSDETAIL) * n);
  152. while (n--)
  153. {
  154. UINT n2 = paiIn->pClasses[n].cProgId;
  155. if (n2)
  156. {
  157. paiOut->pClasses[n].prgProgId = (LPOLESTR *) OLEALLOC(sizeof(LPOLESTR) * n2);
  158. if (!paiOut->pClasses[n].prgProgId)
  159. {
  160. goto out_of_memory;
  161. }
  162. while (n2--)
  163. {
  164. OLESAFE_COPYSTRING(paiOut->pClasses[n].prgProgId[n2], paiIn->pClasses[n].prgProgId[n2]);
  165. }
  166. }
  167. }
  168. }
  169. n = paiIn->cShellFileExt;
  170. if (n)
  171. {
  172. paiOut->prgPriority = (UINT *) OLEALLOC(sizeof(UINT) * n);
  173. if (!paiOut->prgPriority)
  174. {
  175. goto out_of_memory;
  176. }
  177. memcpy(paiOut->prgPriority, paiIn->prgPriority, sizeof(UINT) * n);
  178. paiOut->prgShellFileExt = (LPOLESTR *) OLEALLOC(sizeof(LPOLESTR) * n);
  179. if (!paiOut->prgShellFileExt)
  180. {
  181. goto out_of_memory;
  182. }
  183. while (n--)
  184. {
  185. OLESAFE_COPYSTRING(paiOut->prgShellFileExt[n], paiIn->prgShellFileExt[n]);
  186. }
  187. }
  188. n = paiIn->cInterfaces;
  189. if (n)
  190. {
  191. paiOut->prgInterfaceId = (IID *) OLEALLOC(sizeof(IID) * n);
  192. if (!paiOut->prgInterfaceId)
  193. {
  194. goto out_of_memory;
  195. }
  196. memcpy(paiOut->prgInterfaceId, paiIn->prgInterfaceId, sizeof(IID) * n);
  197. }
  198. n = paiIn->cTypeLib;
  199. if (n)
  200. {
  201. paiOut->prgTlbId = (GUID *) OLEALLOC(sizeof(GUID) * n);
  202. if (!paiOut->prgTlbId)
  203. {
  204. goto out_of_memory;
  205. }
  206. memcpy(paiOut->prgTlbId, paiIn->prgTlbId, sizeof(GUID) * n);
  207. }
  208. return S_OK;
  209. out_of_memory:
  210. FreeActInfo(paiOut);
  211. return E_OUTOFMEMORY;
  212. }
  213. void FreeInstallInfo(INSTALLINFO * &piiOut)
  214. {
  215. if (piiOut)
  216. {
  217. if (piiOut->prgUpgradeInfoList)
  218. {
  219. UINT n = piiOut->cUpgrades;
  220. while (n--)
  221. {
  222. OLESAFE_DELETE(piiOut->prgUpgradeInfoList[n].szClassStore);
  223. }
  224. OLESAFE_DELETE(piiOut->prgUpgradeInfoList);
  225. }
  226. OLESAFE_DELETE(piiOut->pClsid);
  227. OLESAFE_DELETE(piiOut->pszScriptPath);
  228. OLESAFE_DELETE(piiOut->pszSetupCommand);
  229. OLESAFE_DELETE(piiOut->pszUrl);
  230. OLESAFE_DELETE(piiOut);
  231. }
  232. }
  233. HRESULT CopyInstallInfo(INSTALLINFO * & piiOut, INSTALLINFO * & piiIn)
  234. {
  235. ULONG n;
  236. if (NULL == piiIn)
  237. {
  238. piiOut = NULL;
  239. return S_OK;
  240. }
  241. piiOut = (INSTALLINFO *) OLEALLOC(sizeof(INSTALLINFO));
  242. if (!piiOut)
  243. {
  244. goto out_of_memory;
  245. }
  246. memcpy(piiOut, piiIn, sizeof(INSTALLINFO));
  247. piiOut->pClsid = NULL;
  248. piiOut->prgUpgradeInfoList = NULL;
  249. piiOut->pszScriptPath = NULL;
  250. piiOut->pszSetupCommand = NULL;
  251. piiOut->pszUrl = NULL;
  252. OLESAFE_COPYSTRING(piiOut->pszScriptPath, piiIn->pszScriptPath);
  253. OLESAFE_COPYSTRING(piiOut->pszSetupCommand, piiIn->pszSetupCommand);
  254. OLESAFE_COPYSTRING(piiOut->pszUrl, piiIn->pszUrl);
  255. if (piiIn->pClsid)
  256. {
  257. piiOut->pClsid = (GUID *) OLEALLOC(sizeof(GUID));
  258. if (!piiOut->pClsid)
  259. {
  260. goto out_of_memory;
  261. }
  262. memcpy(piiOut->pClsid, piiIn->pClsid, sizeof(GUID));
  263. }
  264. n = piiIn->cUpgrades;
  265. if (n)
  266. {
  267. piiOut->prgUpgradeInfoList = (UPGRADEINFO *) OLEALLOC(sizeof(UPGRADEINFO) * n);
  268. if (!piiOut->prgUpgradeInfoList)
  269. {
  270. goto out_of_memory;
  271. }
  272. memcpy(piiOut->prgUpgradeInfoList, piiIn->prgUpgradeInfoList, sizeof(UPGRADEINFO) * n);
  273. while (n--)
  274. {
  275. OLESAFE_COPYSTRING(piiOut->prgUpgradeInfoList[n].szClassStore, piiIn->prgUpgradeInfoList[n].szClassStore);
  276. }
  277. }
  278. return S_OK;
  279. out_of_memory:
  280. FreeInstallInfo(piiOut);
  281. return E_OUTOFMEMORY;
  282. }
  283. void InternalFreePackageDetail(PACKAGEDETAIL * &ppdOut)
  284. {
  285. if (ppdOut)
  286. {
  287. FreeActInfo(ppdOut->pActInfo);
  288. FreePlatformInfo(ppdOut->pPlatformInfo);
  289. FreeInstallInfo(ppdOut->pInstallInfo);
  290. OLESAFE_DELETE(ppdOut->pszPackageName);
  291. OLESAFE_DELETE(ppdOut->pszPublisher);
  292. if (ppdOut->pszSourceList)
  293. {
  294. UINT n = ppdOut->cSources;
  295. while (n--)
  296. {
  297. OLESAFE_DELETE(ppdOut->pszSourceList[n]);
  298. }
  299. OLESAFE_DELETE(ppdOut->pszSourceList);
  300. }
  301. OLESAFE_DELETE(ppdOut->rpCategory);
  302. }
  303. }
  304. HRESULT CopyPackageDetail(PACKAGEDETAIL * & ppdOut, PACKAGEDETAIL * & ppdIn)
  305. {
  306. ULONG n;
  307. if (NULL == ppdIn)
  308. {
  309. ppdOut = NULL;
  310. return S_OK;
  311. }
  312. ppdOut = new PACKAGEDETAIL;
  313. if (!ppdOut)
  314. {
  315. goto out_of_memory;
  316. }
  317. memcpy(ppdOut, ppdIn, sizeof(PACKAGEDETAIL));
  318. ppdOut->pActInfo = NULL;
  319. ppdOut->pInstallInfo = NULL;
  320. ppdOut->pPlatformInfo = NULL;
  321. ppdOut->pszPackageName = NULL;
  322. ppdOut->pszPublisher = NULL;
  323. ppdOut->pszSourceList = NULL;
  324. ppdOut->rpCategory = NULL;
  325. OLESAFE_COPYSTRING(ppdOut->pszPackageName, ppdIn->pszPackageName);
  326. n = ppdIn->cSources;
  327. if (n)
  328. {
  329. ppdOut->pszSourceList = (LPOLESTR *) OLEALLOC(sizeof(LPOLESTR) * n);
  330. if (!ppdOut->pszSourceList)
  331. {
  332. goto out_of_memory;
  333. }
  334. while (n--)
  335. {
  336. OLESAFE_COPYSTRING(ppdOut->pszSourceList[n], ppdIn->pszSourceList[n]);
  337. }
  338. }
  339. n = ppdIn->cCategories;
  340. if (n)
  341. {
  342. ppdOut->rpCategory = (GUID *)OLEALLOC(sizeof(GUID) * n);
  343. if (!ppdOut->rpCategory)
  344. {
  345. goto out_of_memory;
  346. }
  347. memcpy(ppdOut->rpCategory, ppdIn->rpCategory, sizeof(GUID) * n);
  348. }
  349. if FAILED(CopyActInfo(ppdOut->pActInfo, ppdIn->pActInfo))
  350. goto out_of_memory;
  351. if FAILED(CopyPlatformInfo(ppdOut->pPlatformInfo, ppdIn->pPlatformInfo))
  352. goto out_of_memory;
  353. if FAILED(CopyInstallInfo(ppdOut->pInstallInfo, ppdIn->pInstallInfo))
  354. goto out_of_memory;
  355. return S_OK;
  356. out_of_memory:
  357. LogADEEvent(EVENTLOG_ERROR_TYPE, EVENT_ADE_GENERAL_ERROR, E_OUTOFMEMORY);
  358. InternalFreePackageDetail(ppdOut);
  359. if (ppdOut)
  360. delete ppdOut;
  361. return E_OUTOFMEMORY;
  362. }
  363. void FreePackageDetail(PACKAGEDETAIL * & ppd)
  364. {
  365. if (ppd)
  366. {
  367. ReleasePackageDetail(ppd);
  368. delete ppd;
  369. ppd = NULL;
  370. }
  371. }
  372. //+--------------------------------------------------------------------------
  373. //
  374. // Member: CScopePane::GetUniquePackageName
  375. //
  376. // Synopsis: Returns a unique package name.
  377. //
  378. // Arguments: [sz] - [in] the name of the package
  379. // [out] the new name, guaranteed unique on this cs
  380. //
  381. // History: 1-23-1998 stevebl Created
  382. //
  383. // Notes: First the input name is checked for uniqueness. If it is
  384. // already unique it is returned unchanged. If it is not
  385. // unique then a new name is formed by adding " (2)" to the end
  386. // of the string, then " (3)" and " (4)" and so on until a
  387. // unique name is found.
  388. //
  389. // If you don't want a number appended to the name, nHint must
  390. // be 1.
  391. //
  392. // The value passed back in nHint will be the seed for the
  393. // next try.
  394. //
  395. //---------------------------------------------------------------------------
  396. void CScopePane::GetUniquePackageName(CString szRoot, CString &szOut, int &nHint)
  397. {
  398. map<MMC_COOKIE, CAppData>::iterator i;
  399. set<CString> sNames;
  400. int cch = szRoot.GetLength();
  401. for (i=m_AppData.begin(); i != m_AppData.end(); i++)
  402. {
  403. // As an optimization, I'm only going to add names that might match
  404. // this one to the set.
  405. LPOLESTR szName = i->second.m_pDetails->pszPackageName;
  406. if ((0 == wcsncmp(szRoot, szName, cch)) && (i->second.m_fVisible))
  407. sNames.insert(szName);
  408. }
  409. szOut = szRoot;
  410. if (nHint++ == 1) // try the first name
  411. {
  412. if (sNames.end() == sNames.find(szOut))
  413. return;
  414. }
  415. // now check for a match
  416. do
  417. {
  418. szOut.Format(L"%s (%i)", (LPCTSTR)szRoot, nHint++);
  419. if (sNames.end() == sNames.find(szOut))
  420. {
  421. // we are unique
  422. return;
  423. }
  424. // try a different name
  425. } while (TRUE);
  426. }
  427. //+--------------------------------------------------------------------------
  428. //
  429. // Member: CScopePand::GetDeploymentType
  430. //
  431. // Synopsis:
  432. //
  433. // Arguments: [szPackagePath] -
  434. // [lpFileTitle] -
  435. //
  436. // Returns:
  437. //
  438. // Modifies:
  439. //
  440. // Derivation:
  441. //
  442. // History: 6-29-1998 stevebl Created
  443. //
  444. // Notes:
  445. //
  446. //---------------------------------------------------------------------------
  447. HRESULT CScopePane::GetDeploymentType(PACKAGEDETAIL * ppd, BOOL & fShowPropertySheet)
  448. {
  449. INSTALLINFO * pii = ppd->pInstallInfo;
  450. if (m_ToolDefaults.fUseWizard)
  451. {
  452. CDeployApp dlgDeployApp;
  453. // Turn on theme'ing for the dialog by activating the theme context
  454. CThemeContextActivator themer;
  455. dlgDeployApp.m_fMachine = m_fMachine;
  456. dlgDeployApp.m_fCrappyZaw = pii->PathType == SetupNamePath;
  457. if (IDCANCEL == dlgDeployApp.DoModal())
  458. {
  459. return E_FAIL;
  460. }
  461. switch (dlgDeployApp.m_iDeployment)
  462. {
  463. default:
  464. case 0: //published
  465. pii->dwActFlags = ACTFLG_Published | ACTFLG_UserInstall | ACTFLG_OnDemandInstall;
  466. break;
  467. case 1: // assigned
  468. pii->dwActFlags = ACTFLG_Assigned | ACTFLG_UserInstall | ACTFLG_OnDemandInstall;
  469. break;
  470. case 3: // disabled
  471. pii->dwActFlags = 0;
  472. break;
  473. case 2: // custom
  474. if (m_fMachine)
  475. {
  476. pii->dwActFlags = ACTFLG_Assigned | ACTFLG_UserInstall | ACTFLG_OnDemandInstall;
  477. }
  478. else
  479. {
  480. pii->dwActFlags = ACTFLG_Published | ACTFLG_UserInstall | ACTFLG_OnDemandInstall;
  481. }
  482. fShowPropertySheet = TRUE;
  483. }
  484. }
  485. else
  486. {
  487. switch (m_ToolDefaults.NPBehavior)
  488. {
  489. default:
  490. case NP_PUBLISHED:
  491. if (!m_fMachine)
  492. {
  493. pii->dwActFlags = ACTFLG_Published | ACTFLG_UserInstall | ACTFLG_OnDemandInstall;
  494. break;
  495. }
  496. case NP_ASSIGNED:
  497. if (pii->PathType != SetupNamePath)
  498. {
  499. pii->dwActFlags = ACTFLG_Assigned | ACTFLG_UserInstall | ACTFLG_OnDemandInstall;
  500. }
  501. else
  502. {
  503. // Crappy ZAW app.. force it to be published.
  504. pii->dwActFlags = ACTFLG_Published | ACTFLG_UserInstall | ACTFLG_OnDemandInstall;
  505. }
  506. break;
  507. case NP_DISABLED:
  508. pii->dwActFlags = 0;
  509. break;
  510. }
  511. if (m_ToolDefaults.fCustomDeployment)
  512. {
  513. fShowPropertySheet = TRUE;
  514. }
  515. }
  516. return S_OK;
  517. }
  518. //+--------------------------------------------------------------------------
  519. //
  520. // Member: CScopePane::DeployPackage
  521. //
  522. // Synopsis:
  523. //
  524. // Arguments: [hr] -
  525. // [hr] -
  526. //
  527. // Returns:
  528. //
  529. // Modifies:
  530. //
  531. // Derivation:
  532. //
  533. // History: 6-29-1998 stevebl Created
  534. //
  535. // Notes:
  536. //
  537. //---------------------------------------------------------------------------
  538. HRESULT CScopePane::DeployPackage(PACKAGEDETAIL * ppd, BOOL fShowPropertySheet)
  539. {
  540. CHourglass hourglass;
  541. INSTALLINFO * pii = ppd->pInstallInfo;
  542. HRESULT hrDeploy = S_OK;
  543. hrDeploy = PrepareExtensions(*ppd);
  544. if (SUCCEEDED(hrDeploy))
  545. {
  546. DWORD dwRememberFlags;
  547. // put the entry in the class store
  548. if (fShowPropertySheet)
  549. {
  550. dwRememberFlags = pii->dwActFlags;
  551. pii->dwActFlags = 0; // disabled state
  552. }
  553. if (!m_pIClassAdmin)
  554. {
  555. hrDeploy = GetClassStore(TRUE);
  556. if (FAILED(hrDeploy))
  557. {
  558. LogADEEvent(EVENTLOG_ERROR_TYPE, EVENT_ADE_NOCLASSSTORE_ERROR, hrDeploy);
  559. DebugMsg((DM_WARNING, TEXT("GetClassStore failed with 0x%x"), hrDeploy));
  560. }
  561. }
  562. if (SUCCEEDED(hrDeploy))
  563. {
  564. hrDeploy = m_pIClassAdmin->AddPackage(ppd, &ppd->pInstallInfo->PackageGuid);
  565. if (FAILED(hrDeploy))
  566. {
  567. LogADEEvent(EVENTLOG_ERROR_TYPE, EVENT_ADE_ADDPACKAGE_ERROR, hrDeploy, ppd->pszPackageName);
  568. DebugMsg((DM_WARNING, TEXT("AddPackage failed with 0x%x"), hrDeploy));
  569. }
  570. }
  571. if (FAILED(hrDeploy))
  572. {
  573. return hrDeploy;
  574. }
  575. if (fShowPropertySheet)
  576. {
  577. pii->dwActFlags = dwRememberFlags; // restore state
  578. }
  579. }
  580. if (SUCCEEDED(hrDeploy))
  581. {
  582. CString szCSPath;
  583. hrDeploy = GetClassStoreName(szCSPath, FALSE);
  584. if (FAILED(hrDeploy))
  585. {
  586. DebugMsg((DM_WARNING, TEXT("GetClassStoreName failed with 0x%x"), hrDeploy));
  587. return hrDeploy;
  588. }
  589. CAppData data;
  590. hrDeploy = CopyPackageDetail(data.m_pDetails, ppd);
  591. if (FAILED(hrDeploy))
  592. {
  593. DebugMsg((DM_WARNING, TEXT("CopyPackageDetail failed with 0x%x"), hrDeploy));
  594. return hrDeploy;
  595. }
  596. data.InitializeExtraInfo();
  597. m_lLastAllocated++;
  598. // make sure that m_lLastAllocated hasn't already been used
  599. while (m_AppData.end() != m_AppData.find(m_lLastAllocated))
  600. {
  601. m_lLastAllocated++;
  602. }
  603. data.m_fVisible = FALSE;
  604. m_AppData[m_lLastAllocated] = data;
  605. BOOL fAddOk = TRUE;
  606. // The admin has said he wants to do a "custom" deployment.
  607. if (fShowPropertySheet)
  608. {
  609. HRESULT hr; // errors that happen while setting up
  610. // the property sheets are NOT to be
  611. // reported as deployment errors.
  612. MMC_COOKIE cookie = m_lLastAllocated;
  613. PROPSHEETHEADER psh;
  614. memset(&psh, 0, sizeof(psh));
  615. psh.dwSize = sizeof(psh);
  616. psh.dwFlags = PSH_NOAPPLYNOW | PSH_PROPTITLE;
  617. psh.pszCaption = m_AppData[m_lLastAllocated].m_pDetails->pszPackageName;
  618. int nPage = 0;
  619. HPROPSHEETPAGE rgPages[6];
  620. psh.phpage = rgPages;
  621. //
  622. // Create the Product property page
  623. //
  624. CProduct prpProduct;
  625. prpProduct.m_fPreDeploy = TRUE;
  626. prpProduct.m_pData = &m_AppData[m_lLastAllocated];
  627. prpProduct.m_cookie = cookie;
  628. prpProduct.m_pScopePane = this;
  629. prpProduct.m_pAppData = &m_AppData;
  630. prpProduct.m_pIGPEInformation = m_pIGPEInformation;
  631. prpProduct.m_fMachine = m_fMachine;
  632. prpProduct.m_fRSOP = m_fRSOP;
  633. // no longer need to marshal this interface, just set it
  634. prpProduct.m_pIClassAdmin = m_pIClassAdmin;
  635. m_pIClassAdmin->AddRef();
  636. rgPages[nPage++] = CreateThemedPropertySheetPage(&prpProduct.m_psp);
  637. //
  638. // Create the Depeployment property page
  639. //
  640. CDeploy prpDeploy;
  641. prpDeploy.m_fPreDeploy = TRUE;
  642. prpDeploy.m_pData = &m_AppData[m_lLastAllocated];
  643. prpDeploy.m_cookie = cookie;
  644. prpDeploy.m_fMachine = m_fMachine;
  645. prpDeploy.m_fRSOP = m_fRSOP;
  646. prpDeploy.m_pScopePane = this;
  647. #if 0
  648. prpDeploy.m_pIGPEInformation = m_pIGPEInformation;
  649. #endif
  650. // no longer need to marshal this interface, just set it
  651. prpDeploy.m_pIClassAdmin = m_pIClassAdmin;
  652. m_pIClassAdmin->AddRef();
  653. rgPages[nPage++] = CreateThemedPropertySheetPage(&prpDeploy.m_psp);
  654. CUpgradeList prpUpgradeList;
  655. if (pii->PathType != SetupNamePath)
  656. {
  657. //
  658. // Create the upgrades property page
  659. //
  660. prpUpgradeList.m_pData = &m_AppData[m_lLastAllocated];
  661. prpUpgradeList.m_cookie = cookie;
  662. prpUpgradeList.m_pScopePane = this;
  663. prpUpgradeList.m_fPreDeploy = TRUE;
  664. prpUpgradeList.m_fMachine = m_fMachine;
  665. prpUpgradeList.m_fRSOP = m_fRSOP;
  666. #if 0
  667. prpUpgradeList.m_pIGPEInformation = m_pIGPEInformation;
  668. #endif
  669. // no longer need to marshal the interface, just set it
  670. prpUpgradeList.m_pIClassAdmin = m_pIClassAdmin;
  671. m_pIClassAdmin->AddRef();
  672. rgPages[nPage++] = CreateThemedPropertySheetPage(&prpUpgradeList.m_psp);
  673. }
  674. //
  675. // make sure we have an up-to-date categories list
  676. //
  677. ClearCategories();
  678. hr = CsGetAppCategories(&m_CatList);
  679. if (FAILED(hr))
  680. {
  681. // report it
  682. LogADEEvent(EVENTLOG_ERROR_TYPE, EVENT_ADE_GETCATEGORIES_ERROR, hr, NULL);
  683. // Since failure only means the categories list will be
  684. // empty, we'll proceed as if nothing happened.
  685. hr = S_OK;
  686. }
  687. //
  688. // Create the Category property page
  689. //
  690. CCategory prpCategory;
  691. prpCategory.m_pData = &m_AppData[m_lLastAllocated];
  692. prpCategory.m_cookie = cookie;
  693. prpCategory.m_pCatList = &m_CatList;
  694. prpCategory.m_fRSOP = m_fRSOP;
  695. prpCategory.m_fPreDeploy = TRUE;
  696. // no longer need to marshal this interface, just set it
  697. prpCategory.m_pIClassAdmin = m_pIClassAdmin;
  698. m_pIClassAdmin->AddRef();
  699. rgPages[nPage++] = CreateThemedPropertySheetPage(&prpCategory.m_psp);
  700. CXforms prpXforms;
  701. if (pii->PathType != SetupNamePath)
  702. {
  703. //
  704. // Create the Xforms property page
  705. //
  706. prpXforms.m_fPreDeploy = TRUE;
  707. prpXforms.m_pData = &m_AppData[m_lLastAllocated];
  708. prpXforms.m_cookie = cookie;
  709. prpXforms.m_pScopePane = this;
  710. // no longer need to marshal the interface, just set it
  711. prpXforms.m_pIClassAdmin = m_pIClassAdmin;
  712. m_pIClassAdmin->AddRef();
  713. rgPages[nPage++] = CreateThemedPropertySheetPage(&prpXforms.m_psp);
  714. }
  715. //
  716. // Create the security property page
  717. //
  718. CString szPath;
  719. hr = GetPackageDSPath(szPath, m_AppData[m_lLastAllocated].m_pDetails->pszPackageName);
  720. if (SUCCEEDED(hr))
  721. {
  722. LPSECURITYINFO pSI;
  723. hr = DSCreateISecurityInfoObject(szPath,
  724. NULL,
  725. 0,
  726. &pSI,
  727. NULL,
  728. NULL,
  729. 0);
  730. if (SUCCEEDED(hr))
  731. {
  732. rgPages[nPage++] = CreateSecurityPage(pSI);
  733. pSI->Release();
  734. }
  735. else
  736. {
  737. DebugMsg((DM_WARNING, TEXT("DSCreateISecurityInfoObject failed with 0x%x"), hr));
  738. }
  739. }
  740. else
  741. {
  742. DebugMsg((DM_WARNING, TEXT("GetPackageDSPath failed with 0x%x"), hr));
  743. }
  744. psh.nPages = nPage;
  745. psh.hwndParent = m_hwndMainWindow;
  746. if (IDOK != PropertySheet(&psh))
  747. {
  748. fAddOk = FALSE;
  749. RemovePackage(cookie, FALSE, TRUE);
  750. }
  751. else
  752. {
  753. // Make sure that the package is deployed with the proper
  754. // deployment type
  755. hr = m_pIClassAdmin->ChangePackageProperties(m_AppData[m_lLastAllocated].m_pDetails->pszPackageName,
  756. NULL,
  757. &m_AppData[m_lLastAllocated].m_pDetails->pInstallInfo->dwActFlags,
  758. NULL,
  759. NULL,
  760. NULL,
  761. NULL);
  762. if (SUCCEEDED(hr))
  763. {
  764. if (FAILED(m_pIGPEInformation->PolicyChanged(m_fMachine, TRUE, &guidExtension,
  765. m_fMachine ? &guidMachSnapin
  766. : &guidUserSnapin )))
  767. {
  768. ReportPolicyChangedError(m_hwndMainWindow);
  769. }
  770. }
  771. }
  772. }
  773. if (fAddOk)
  774. {
  775. set <CResultPane *>::iterator i;
  776. for (i = m_sResultPane.begin(); i != m_sResultPane.end(); i++)
  777. {
  778. RESULTDATAITEM resultItem;
  779. memset(&resultItem, 0, sizeof(resultItem));
  780. if ((*i)->_fVisible)
  781. {
  782. resultItem.mask = RDI_STR | RDI_IMAGE | RDI_PARAM;
  783. resultItem.str = MMC_CALLBACK;
  784. resultItem.nImage = m_AppData[m_lLastAllocated].GetImageIndex(this);
  785. resultItem.lParam = m_lLastAllocated;
  786. hrDeploy = (*i)->m_pResult->InsertItem(&resultItem);
  787. }
  788. // The following code must be excecuted wheather the InsertItem
  789. // call succeeds or not.
  790. // There are legitimate cases when InsertItem will fail. For
  791. // instance, if the scope pane is being shown, but not the
  792. // result pane.
  793. m_AppData[m_lLastAllocated].m_fVisible = TRUE;
  794. m_AppData[m_lLastAllocated].m_itemID = resultItem.itemID;
  795. InsertExtensionEntry(m_lLastAllocated, m_AppData[m_lLastAllocated]);
  796. if (m_pFileExt)
  797. {
  798. m_pFileExt->SendMessage(WM_USER_REFRESH, 0, 0);
  799. }
  800. InsertUpgradeEntry(m_lLastAllocated, m_AppData[m_lLastAllocated]);
  801. m_UpgradeIndex[GetUpgradeIndex(m_AppData[m_lLastAllocated].m_pDetails->pInstallInfo->PackageGuid)] = m_lLastAllocated;
  802. // if this is an upgrade, set icons for upgraded apps to
  803. // the proper icon and refresh any open property sheets
  804. UINT n = m_AppData[m_lLastAllocated].m_pDetails->pInstallInfo->cUpgrades;
  805. while (n--)
  806. {
  807. map<CString, MMC_COOKIE>::iterator i = m_UpgradeIndex.find(GetUpgradeIndex(m_AppData[m_lLastAllocated].m_pDetails->pInstallInfo->prgUpgradeInfoList[n].PackageGuid));
  808. if (i != m_UpgradeIndex.end())
  809. {
  810. if (m_AppData[i->second].m_pUpgradeList)
  811. {
  812. m_AppData[i->second].m_pUpgradeList->SendMessage(WM_USER_REFRESH, 0, 0);
  813. }
  814. }
  815. }
  816. if ((*i)->_fVisible)
  817. {
  818. if (SUCCEEDED(hrDeploy))
  819. {
  820. (*i)->m_pResult->SetItem(&resultItem);
  821. (*i)->m_pResult->Sort((*i)->m_nSortColumn, (*i)->m_dwSortOptions, -1);
  822. }
  823. else
  824. {
  825. DebugMsg((DM_WARNING, TEXT("InsertItem failed with 0x%x"), hrDeploy));
  826. hrDeploy = S_OK;
  827. }
  828. }
  829. }
  830. }
  831. }
  832. return hrDeploy;
  833. }
  834. //+--------------------------------------------------------------------------
  835. //
  836. // Member: CScopePane::AddZAPPackage
  837. //
  838. // Synopsis:
  839. //
  840. // Arguments: [szPackagePath] -
  841. // [lpFileTitle] -
  842. //
  843. // Returns:
  844. //
  845. // Modifies:
  846. //
  847. // Derivation:
  848. //
  849. // History: 6-29-1998 stevebl Created
  850. //
  851. // Notes:
  852. //
  853. //---------------------------------------------------------------------------
  854. HRESULT CScopePane::AddZAPPackage(LPCOLESTR szPackagePath, LPCOLESTR lpFileTitle)
  855. {
  856. CHourglass hourglass;
  857. HRESULT hr = E_FAIL;
  858. OLECHAR szBuffer[1024];
  859. OLECHAR * sz = szBuffer;
  860. CString szFriendlyName;
  861. CString szUniqueFriendlyName;
  862. int nHint = 1;
  863. DWORD dw = GetPrivateProfileString(
  864. L"Application",
  865. L"FriendlyName",
  866. NULL,
  867. sz,
  868. sizeof(szBuffer) / sizeof(szBuffer[0]),
  869. szPackagePath);
  870. if (0 == dw)
  871. {
  872. // either bogus FriendlyName or no setup command, both of which are fatal
  873. goto bad_script;
  874. }
  875. szFriendlyName = sz; // save this for later
  876. dw = GetPrivateProfileString(
  877. L"Application",
  878. L"SetupCommand",
  879. NULL,
  880. sz,
  881. sizeof(szBuffer) / sizeof(szBuffer[0]),
  882. szPackagePath);
  883. if (0 == dw)
  884. {
  885. // either bogus file or no setup command, both of which are fatal
  886. bad_script:
  887. {
  888. LogADEEvent(EVENTLOG_ERROR_TYPE, EVENT_ADE_BADZAP_ERROR, HRESULT_FROM_WIN32(dw), lpFileTitle);
  889. TCHAR szBadScriptBuffer[256];
  890. ::LoadString(ghInstance, IDS_ADDFAILED_ZAP, szBadScriptBuffer, 256);
  891. m_pConsole->MessageBox(szBadScriptBuffer,
  892. lpFileTitle,
  893. MB_OK | MB_ICONEXCLAMATION, NULL);
  894. }
  895. return E_FAIL;
  896. }
  897. INSTALLINFO * pii = NULL;
  898. PLATFORMINFO * ppi = NULL;
  899. ACTIVATIONINFO * pai = NULL;
  900. PACKAGEDETAIL *ppd = new PACKAGEDETAIL;
  901. if (!ppd)
  902. {
  903. goto out_of_memory;
  904. }
  905. memset(ppd, 0, sizeof(PACKAGEDETAIL));
  906. pii = (INSTALLINFO *) OLEALLOC(sizeof(INSTALLINFO));
  907. ppd->pInstallInfo = pii;
  908. if (!pii)
  909. {
  910. goto out_of_memory;
  911. }
  912. memset(pii, 0, sizeof(INSTALLINFO));
  913. ppi = (PLATFORMINFO *) OLEALLOC(sizeof(PLATFORMINFO));
  914. ppd->pPlatformInfo = ppi;
  915. if (!ppi)
  916. {
  917. goto out_of_memory;
  918. }
  919. memset(ppi, 0, sizeof(PLATFORMINFO));
  920. pai = (ACTIVATIONINFO *) OLEALLOC(sizeof(ACTIVATIONINFO));
  921. ppd->pActInfo = pai;
  922. if (!pai)
  923. {
  924. goto out_of_memory;
  925. }
  926. else
  927. {
  928. memset(pai, 0, sizeof(ACTIVATIONINFO));
  929. pai->bHasClasses = ! m_ToolDefaults.fExtensionsOnly;
  930. // Munge the setup path.
  931. // surround the path in quotes to be sure that spaces are dealt
  932. // with properly
  933. CString szPath = L'"';
  934. szPath += szPackagePath;
  935. // strip off the package name
  936. int ich = szPath.ReverseFind(L'\\');
  937. // check for either slash symbol (just in case)
  938. int ich2 = szPath.ReverseFind(L'/');
  939. if (ich2 > ich)
  940. {
  941. ich = ich2;
  942. }
  943. if (ich >= 0)
  944. {
  945. szPath = szPath.Left(ich + 1); // keep the path separator
  946. }
  947. // merge it with the setup command string
  948. BOOL fNeedQuote = TRUE;
  949. if (sz[0] == L'"')
  950. {
  951. // remember that we had a leading quote (no need to insert a quote)
  952. // and strip it off
  953. sz++;
  954. fNeedQuote = FALSE;
  955. }
  956. while (sz[0])
  957. {
  958. if (sz[0] == L'.' && sz[1] == L'.' && (sz[2] == L'/' || sz[2] == L'\\'))
  959. {
  960. // strip off the last path element
  961. // First strip off the path separator (the one we kept previously)
  962. szPath = szPath.Left(ich);
  963. // now find the symbol
  964. ich = szPath.ReverseFind(L'\\');
  965. // check for either slash symbol (just in case)
  966. ich2 = szPath.ReverseFind(L'/');
  967. if (ich2 > ich)
  968. {
  969. ich = ich2;
  970. }
  971. if (ich >= 0)
  972. {
  973. szPath = szPath.Left(ich + 1); // keep the path separator
  974. }
  975. // skip the "..\"
  976. sz += 3;
  977. }
  978. else
  979. {
  980. if ((0 != sz[0] && L':' == sz[1])
  981. ||
  982. ((L'\\' == sz[0] || L'/' == sz[0]) && (L'\\' == sz[1] || L'/' == sz[1]))
  983. ||
  984. (0 == wcsncmp(L"http:",sz,5)))
  985. {
  986. // hard path
  987. // throw away szPath;
  988. szPath = L"";
  989. if (!fNeedQuote)
  990. {
  991. // make sure we don't drop that quote
  992. szPath += L'"';
  993. }
  994. // and make sure we don't insert quotes where they're not wanted
  995. fNeedQuote = FALSE;
  996. }
  997. // break the loop on anything other than "..\"
  998. break;
  999. }
  1000. }
  1001. if (fNeedQuote)
  1002. {
  1003. CString szTemp = sz;
  1004. // copy everything up to the first space
  1005. ich = szTemp.Find(L' ');
  1006. szPath += szTemp.Left(ich);
  1007. // then add a quote
  1008. szPath += L'"';
  1009. szPath += szTemp.Mid(ich);
  1010. }
  1011. else
  1012. {
  1013. szPath += sz;
  1014. }
  1015. OLESAFE_COPYSTRING(pii->pszScriptPath, szPath);
  1016. sz = szBuffer;
  1017. dw = GetPrivateProfileString(
  1018. L"Application",
  1019. L"DisplayVersion",
  1020. NULL,
  1021. sz,
  1022. sizeof(szBuffer) / sizeof(szBuffer[0]),
  1023. szPackagePath);
  1024. if (dw)
  1025. {
  1026. // parse product version
  1027. CString szProdVersion = szBuffer;
  1028. szProdVersion.TrimLeft();
  1029. CString szTemp = szProdVersion.SpanIncluding(L"0123456789");
  1030. (void) swscanf(szTemp, L"%u", &pii->dwVersionHi);
  1031. szProdVersion = szProdVersion.Mid(szTemp.GetLength());
  1032. szTemp = szProdVersion.SpanExcluding(L"0123456789");
  1033. szProdVersion = szProdVersion.Mid(szTemp.GetLength());
  1034. (void) swscanf(szProdVersion, L"%u", &pii->dwVersionLo);
  1035. }
  1036. dw = GetPrivateProfileString(
  1037. L"Application",
  1038. L"Publisher",
  1039. NULL,
  1040. sz,
  1041. sizeof(szBuffer) / sizeof(szBuffer[0]),
  1042. szPackagePath);
  1043. if (dw)
  1044. {
  1045. OLESAFE_COPYSTRING(ppd->pszPublisher, sz);
  1046. }
  1047. dw = GetPrivateProfileString(
  1048. L"Application",
  1049. L"URL",
  1050. NULL,
  1051. sz,
  1052. sizeof(szBuffer) / sizeof(szBuffer[0]),
  1053. szPackagePath);
  1054. if (dw)
  1055. {
  1056. OLESAFE_COPYSTRING(pii->pszUrl, sz);
  1057. }
  1058. set<DWORD> sPlatforms;
  1059. dw = GetPrivateProfileString(
  1060. L"Application",
  1061. L"Architecture",
  1062. NULL,
  1063. sz,
  1064. sizeof(szBuffer) / sizeof(szBuffer[0]),
  1065. szPackagePath);
  1066. BOOL fValidPlatform;
  1067. fValidPlatform = FALSE;
  1068. if (dw)
  1069. {
  1070. CString szPlatforms = szBuffer;
  1071. CString szTemp;
  1072. while (szPlatforms.GetLength())
  1073. {
  1074. szTemp = szPlatforms.SpanExcluding(L",");
  1075. if (0 == szTemp.CompareNoCase(L"intel"))
  1076. {
  1077. sPlatforms.insert(PROCESSOR_ARCHITECTURE_INTEL);
  1078. fValidPlatform = TRUE;
  1079. }
  1080. else if (0 == szTemp.CompareNoCase(L"amd64"))
  1081. {
  1082. sPlatforms.insert(PROCESSOR_ARCHITECTURE_AMD64);
  1083. fValidPlatform = TRUE;
  1084. }
  1085. else if (0 == szTemp.CompareNoCase(L"intel64"))
  1086. {
  1087. sPlatforms.insert(PROCESSOR_ARCHITECTURE_IA64);
  1088. fValidPlatform = TRUE;
  1089. }
  1090. szPlatforms = szPlatforms.Mid(szTemp.GetLength()+1);
  1091. }
  1092. }
  1093. //
  1094. // Ensure that if we saw any platforms, at least one of them
  1095. // was a supported platform
  1096. //
  1097. if ( dw && ! fValidPlatform )
  1098. {
  1099. ::LoadString(ghInstance, IDS_ILLEGAL_PLATFORM, szBuffer, 256);
  1100. m_pConsole->MessageBox(szBuffer,
  1101. lpFileTitle,
  1102. MB_OK | MB_ICONEXCLAMATION, NULL);
  1103. delete ppd;
  1104. return E_FAIL;
  1105. }
  1106. if (0 == sPlatforms.size())
  1107. {
  1108. // If the ZAP file doesn't specify an architecture
  1109. // then we'll treat is as an x86 package
  1110. sPlatforms.insert(PROCESSOR_ARCHITECTURE_INTEL);
  1111. DebugMsg((DL_VERBOSE, TEXT("No platform detected, assuming x86.")));
  1112. }
  1113. ppi->cPlatforms = sPlatforms.size();
  1114. ppi->prgPlatform = (CSPLATFORM *) OLEALLOC(sizeof(CSPLATFORM) * (ppi->cPlatforms));;
  1115. if (!ppi->prgPlatform)
  1116. {
  1117. ppi->cPlatforms = 0;
  1118. goto out_of_memory;
  1119. }
  1120. INT iIndex=0;
  1121. set<DWORD>::iterator iPlatform;
  1122. for (iPlatform = sPlatforms.begin(); iPlatform != sPlatforms.end(); iPlatform++, iIndex++)
  1123. {
  1124. ppi->prgPlatform[iIndex].dwPlatformId = VER_PLATFORM_WIN32_NT;
  1125. ppi->prgPlatform[iIndex].dwVersionHi = 5;
  1126. ppi->prgPlatform[iIndex].dwVersionLo = 0;
  1127. ppi->prgPlatform[iIndex].dwProcessorArch = *iPlatform;
  1128. }
  1129. ppi->prgLocale = (LCID *) OLEALLOC(sizeof(LCID));
  1130. if (!ppi->prgLocale)
  1131. {
  1132. goto out_of_memory;
  1133. }
  1134. ppi->cLocales = 1;
  1135. ppi->prgLocale[0] = 0; // if none is supplied we assume language neutral
  1136. dw = GetPrivateProfileString(
  1137. L"Application",
  1138. L"LCID",
  1139. NULL,
  1140. sz,
  1141. sizeof(szBuffer) / sizeof(szBuffer[0]),
  1142. szPackagePath);
  1143. if (dw)
  1144. {
  1145. (void) swscanf(szBuffer, L"%i", &ppi->prgLocale[0]);
  1146. // we only deploy one LCID (the primary one)
  1147. }
  1148. // Get the list of extensions
  1149. dw = GetPrivateProfileString(
  1150. L"ext",
  1151. NULL,
  1152. NULL,
  1153. sz,
  1154. sizeof(szBuffer) / sizeof(szBuffer[0]),
  1155. szPackagePath);
  1156. if (dw)
  1157. {
  1158. vector<CString> v;
  1159. TCHAR szName[256];
  1160. while (sz < &szBuffer[dw])
  1161. {
  1162. while ('.' == sz[0])
  1163. sz++;
  1164. CString szExt = ".";
  1165. szExt += sz;
  1166. v.push_back(szExt);
  1167. sz += (wcslen(sz) + 1);
  1168. }
  1169. // build the new list
  1170. UINT n = v.size();
  1171. if (n > 0)
  1172. {
  1173. pai->prgShellFileExt = (LPOLESTR *) OLEALLOC(sizeof(LPOLESTR) * n);
  1174. if (!pai->prgShellFileExt)
  1175. {
  1176. goto out_of_memory;
  1177. }
  1178. pai->prgPriority = (UINT *) OLEALLOC(sizeof(UINT) * n);
  1179. if (!pai->prgPriority)
  1180. {
  1181. goto out_of_memory;
  1182. }
  1183. pai->cShellFileExt = n;
  1184. while (n--)
  1185. {
  1186. CString &szLower = v[n];
  1187. szLower.MakeLower();
  1188. OLESAFE_COPYSTRING(pai->prgShellFileExt[n], szLower);
  1189. pai->prgPriority[n] = 0;
  1190. }
  1191. }
  1192. }
  1193. // get the list of CLSIDs
  1194. vector<CLASSDETAIL> v;
  1195. sz = szBuffer;
  1196. dw = GetPrivateProfileString(
  1197. L"CLSIDs",
  1198. NULL,
  1199. NULL,
  1200. sz,
  1201. sizeof(szBuffer) / sizeof(szBuffer[0]),
  1202. szPackagePath);
  1203. if (dw)
  1204. {
  1205. while (sz < &szBuffer[dw])
  1206. {
  1207. OLECHAR szType[256];
  1208. DWORD dwSubKey = GetPrivateProfileString(
  1209. L"CLSIDs",
  1210. sz,
  1211. NULL,
  1212. szType,
  1213. sizeof(szType) / sizeof(szType[0]),
  1214. szPackagePath);
  1215. CLASSDETAIL cd;
  1216. memset(&cd, 0, sizeof(CLASSDETAIL));
  1217. hr = CLSIDFromString(sz, &cd.Clsid);
  1218. if (SUCCEEDED(hr))
  1219. {
  1220. CString szTypes = szType;
  1221. szTypes.MakeLower();
  1222. if (szTypes.Find(L"inprocserver32") >= 0)
  1223. {
  1224. cd.dwComClassContext |= CLSCTX_INPROC_SERVER;
  1225. }
  1226. if (szTypes.Find(L"localserver32") >= 0)
  1227. {
  1228. cd.dwComClassContext |= CLSCTX_LOCAL_SERVER;
  1229. }
  1230. if (szTypes.Find(L"inprochandler32") >= 0)
  1231. {
  1232. cd.dwComClassContext |= CLSCTX_INPROC_HANDLER;
  1233. }
  1234. v.push_back(cd);
  1235. }
  1236. sz += (wcslen(sz) + 1);
  1237. }
  1238. }
  1239. // get the list of ProgIDs
  1240. sz = szBuffer;
  1241. dw = GetPrivateProfileString(
  1242. L"ProgIDs",
  1243. NULL,
  1244. NULL,
  1245. sz,
  1246. sizeof(szBuffer) / sizeof(szBuffer[0]),
  1247. szPackagePath);
  1248. if (dw)
  1249. {
  1250. while (sz < &szBuffer[dw])
  1251. {
  1252. OLECHAR szType[256];
  1253. DWORD dwSubKey = GetPrivateProfileString(
  1254. L"ProgIDs",
  1255. sz,
  1256. NULL,
  1257. szType,
  1258. sizeof(szType) / sizeof(szType[0]),
  1259. szPackagePath);
  1260. CLSID cid;
  1261. hr = CLSIDFromString(sz, &cid);
  1262. if (SUCCEEDED(hr))
  1263. {
  1264. // Match it to its CLASSDETAIL structure and insert it into the
  1265. // ProgID list.
  1266. // (fat and slow method)
  1267. vector<CLASSDETAIL>::iterator i;
  1268. for (i = v.begin(); i != v.end(); i++)
  1269. {
  1270. if (0 == memcmp(&i->Clsid, &cid, sizeof(CLSID)))
  1271. {
  1272. // found a match
  1273. // hereiam
  1274. vector <CString> vIds;
  1275. CString szAppIds = szType;
  1276. CString szTemp;
  1277. while (szAppIds.GetLength())
  1278. {
  1279. szTemp = szAppIds.SpanExcluding(L",");
  1280. szTemp.TrimLeft();
  1281. vIds.push_back(szTemp);
  1282. szAppIds = szAppIds.Mid(szTemp.GetLength()+1);
  1283. }
  1284. while (i->cProgId--)
  1285. {
  1286. OLESAFE_DELETE(i->prgProgId[i->cProgId]);
  1287. }
  1288. OLESAFE_DELETE(i->prgProgId);
  1289. DWORD cProgId = vIds.size();
  1290. LPOLESTR * prgProgId = (LPOLESTR *)
  1291. OLEALLOC(sizeof(LPOLESTR) * (cProgId));
  1292. if (!prgProgId)
  1293. {
  1294. goto out_of_memory;
  1295. }
  1296. i->cProgId = cProgId;
  1297. while (cProgId--)
  1298. {
  1299. OLESAFE_COPYSTRING(prgProgId[cProgId], vIds[cProgId]);
  1300. }
  1301. i->prgProgId = prgProgId;
  1302. }
  1303. }
  1304. }
  1305. sz += (wcslen(sz) + 1);
  1306. }
  1307. }
  1308. // create the list of CLASSDETAIL structures
  1309. {
  1310. UINT n = v.size();
  1311. if (n > 0)
  1312. {
  1313. pai->pClasses = (CLASSDETAIL *) OLEALLOC(sizeof(CLASSDETAIL) * n);
  1314. if (!pai->pClasses)
  1315. {
  1316. goto out_of_memory;
  1317. }
  1318. pai->cClasses = n;
  1319. while (n--)
  1320. {
  1321. pai->pClasses[n] = v[n];
  1322. }
  1323. }
  1324. }
  1325. ppd->pszSourceList = (LPOLESTR *) OLEALLOC(sizeof(LPOLESTR));
  1326. if (!ppd->pszSourceList)
  1327. {
  1328. goto out_of_memory;
  1329. }
  1330. ppd->cSources = 1;
  1331. OLESAFE_COPYSTRING(ppd->pszSourceList[0], szPackagePath);
  1332. GetUniquePackageName(szFriendlyName, szUniqueFriendlyName, nHint);
  1333. OLESAFE_COPYSTRING(ppd->pszPackageName, szUniqueFriendlyName);
  1334. // Popup UI
  1335. pii->PathType = SetupNamePath;
  1336. BOOL fShowPropertyPage = FALSE;
  1337. hr = GetDeploymentType(ppd, fShowPropertyPage);
  1338. if (SUCCEEDED(hr))
  1339. {
  1340. CHourglass hourglass;
  1341. if (m_ToolDefaults.fZapOn64)
  1342. {
  1343. pii->dwActFlags |= ACTFLG_ExcludeX86OnWin64; // same as ACTFLG_ZAP_IncludeX86OfWin64
  1344. }
  1345. do
  1346. {
  1347. hr = DeployPackage(ppd, fShowPropertyPage);
  1348. if (hr == CS_E_OBJECT_ALREADY_EXISTS)
  1349. {
  1350. OLESAFE_DELETE(ppd->pszPackageName);
  1351. GetUniquePackageName(szFriendlyName, szUniqueFriendlyName, nHint);
  1352. OLESAFE_COPYSTRING(ppd->pszPackageName, szUniqueFriendlyName);
  1353. }
  1354. } while (hr == CS_E_OBJECT_ALREADY_EXISTS);
  1355. }
  1356. if (FAILED(hr) && hr != E_FAIL) // don't report E_FAIL error
  1357. // because it's a benign error
  1358. // (probably a dialog cancellation)
  1359. {
  1360. // report the error in the event log
  1361. LogADEEvent(EVENTLOG_ERROR_TYPE, EVENT_ADE_DEPLOYMENT_ERROR, hr, lpFileTitle);
  1362. // now try to come up with a meaningful message for the user
  1363. if (HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED) == hr)
  1364. {
  1365. // access permission failure
  1366. ::LoadString(ghInstance, IDS_ADDFAILED_ACCESS_DENIED, szBuffer, 256);
  1367. }
  1368. else
  1369. {
  1370. switch (hr)
  1371. {
  1372. // For these errors, we'll report the party line:
  1373. case CS_E_CLASS_NOTFOUND:
  1374. case CS_E_INVALID_VERSION:
  1375. case CS_E_NO_CLASSSTORE:
  1376. case CS_E_OBJECT_NOTFOUND:
  1377. case CS_E_OBJECT_ALREADY_EXISTS:
  1378. case CS_E_INVALID_PATH:
  1379. case CS_E_NETWORK_ERROR:
  1380. case CS_E_ADMIN_LIMIT_EXCEEDED:
  1381. case CS_E_SCHEMA_MISMATCH:
  1382. case CS_E_PACKAGE_NOTFOUND:
  1383. case CS_E_INTERNAL_ERROR:
  1384. {
  1385. dw = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
  1386. NULL,
  1387. hr,
  1388. 0,
  1389. szBuffer,
  1390. sizeof(szBuffer) / sizeof(szBuffer[0]),
  1391. NULL);
  1392. if (0 != dw)
  1393. {
  1394. // got a valid message string
  1395. break;
  1396. }
  1397. // otherwise fall through and give the generic message
  1398. }
  1399. // Either these CS errors don't apply or an admin
  1400. // wouldn't know what they mean:
  1401. case CS_E_NOT_DELETABLE:
  1402. default:
  1403. // generic class store problem
  1404. ::LoadString(ghInstance, IDS_ADDFAILED_CSFAILURE, szBuffer, 256);
  1405. break;
  1406. }
  1407. }
  1408. #if DBG
  1409. TCHAR szDebugBuffer[256];
  1410. dw = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
  1411. NULL,
  1412. hr,
  1413. 0,
  1414. szDebugBuffer,
  1415. sizeof(szDebugBuffer) / sizeof(szDebugBuffer[0]),
  1416. NULL);
  1417. if (0 == dw)
  1418. {
  1419. (void) StringCchPrintf(szDebugBuffer,
  1420. sizeof(szDebugBuffer)/sizeof(szDebugBuffer[0]),
  1421. TEXT("(HRESULT: 0x%lX)"),
  1422. hr);
  1423. }
  1424. (void) StringCchCat(szBuffer,
  1425. sizeof(szBuffer) / sizeof(szBuffer[0]),
  1426. szDebugBuffer);
  1427. #endif
  1428. m_pConsole->MessageBox(szBuffer,
  1429. lpFileTitle,
  1430. MB_OK | MB_ICONEXCLAMATION, NULL);
  1431. }
  1432. FreePackageDetail(ppd);
  1433. }
  1434. return hr;
  1435. out_of_memory:
  1436. if (ppd)
  1437. {
  1438. LogADEEvent(EVENTLOG_ERROR_TYPE, EVENT_ADE_GENERAL_ERROR, E_OUTOFMEMORY);
  1439. InternalFreePackageDetail(ppd);
  1440. delete ppd;
  1441. }
  1442. return E_OUTOFMEMORY;
  1443. }
  1444. //+--------------------------------------------------------------------------
  1445. //
  1446. // Member: CScopePane::AddMSIPackage
  1447. //
  1448. // Synopsis: Add's one or more packages to the class store and adds the
  1449. // appropriate entries to the result pane.
  1450. //
  1451. // Arguments: [szPackagePath] - Full path to the Darwin package.
  1452. // [lpFileTitle] - file title from the open file dialog (used
  1453. // for UI)
  1454. //
  1455. // Returns: S_OK - succeeded
  1456. // E_FAIL - benign failure (probably a cancellation or something)
  1457. // other - significant failure
  1458. //
  1459. // History: 2-03-1998 stevebl Created
  1460. //
  1461. //---------------------------------------------------------------------------
  1462. HRESULT CScopePane::AddMSIPackage(LPCOLESTR szPackagePath, LPCOLESTR lpFileTitle)
  1463. {
  1464. CHourglass hourglass;
  1465. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1466. HRESULT hr = E_FAIL;
  1467. BOOL fPreparationDone = FALSE; // Used to identify if the routine has
  1468. // progressed passed the "prep" stage
  1469. // and is now in the deployment stage.
  1470. // Errors in the earlier part are most
  1471. // likely due to Darwin problems.
  1472. // Errors in teh latter part are most
  1473. // likely due to Class Store problems.
  1474. set<LCID> sLocales;
  1475. CUpgrades dlgUpgrade;
  1476. int nLocales;
  1477. set<LCID>::iterator iLocale;
  1478. PACKAGEDETAIL *ppd = NULL;
  1479. CString szFriendlyName;
  1480. CString szUniqueFriendlyName;
  1481. int nHint = 1;
  1482. ASSERT(m_pConsole);
  1483. {
  1484. BOOL fShowPropertySheet = FALSE;
  1485. GUID guid;
  1486. INSTALLINFO *pii = NULL;
  1487. PLATFORMINFO *ppi = NULL;
  1488. ACTIVATIONINFO *pai = NULL;
  1489. ppd = new PACKAGEDETAIL;
  1490. if (!ppd)
  1491. {
  1492. goto out_of_memory;
  1493. }
  1494. memset(ppd, 0, sizeof(PACKAGEDETAIL));
  1495. pii = (INSTALLINFO *) OLEALLOC(sizeof(INSTALLINFO));
  1496. if (!pii)
  1497. {
  1498. goto out_of_memory;
  1499. }
  1500. memset(pii, 0, sizeof(INSTALLINFO));
  1501. ppi = (PLATFORMINFO *) OLEALLOC(sizeof(PLATFORMINFO));
  1502. ppd->pPlatformInfo = ppi;
  1503. if (!ppi)
  1504. {
  1505. goto out_of_memory;
  1506. }
  1507. ppd->pInstallInfo = pii;
  1508. memset(ppi, 0, sizeof(PLATFORMINFO));
  1509. pai = (ACTIVATIONINFO *) OLEALLOC(sizeof(ACTIVATIONINFO));
  1510. ppd->pActInfo = pai;
  1511. if (!pai)
  1512. {
  1513. goto out_of_memory;
  1514. }
  1515. else
  1516. {
  1517. memset(pai, 0, sizeof(ACTIVATIONINFO));
  1518. pai->bHasClasses = ! m_ToolDefaults.fExtensionsOnly;
  1519. pii->PathType = DrwFilePath;
  1520. hr = GetDeploymentType(ppd, fShowPropertySheet);
  1521. CHourglass hourglass;
  1522. if (FAILED(hr))
  1523. {
  1524. goto done;
  1525. }
  1526. if (!m_ToolDefaults.f32On64)
  1527. {
  1528. pii->dwActFlags |= ACTFLG_ExcludeX86OnWin64; // same as ACTFLG_ZAP_IncludeX86OfWin64
  1529. }
  1530. if (m_ToolDefaults.fUninstallOnPolicyRemoval)
  1531. {
  1532. pii->dwActFlags |= ACTFLG_UninstallOnPolicyRemoval;
  1533. }
  1534. else
  1535. {
  1536. pii->dwActFlags |= ACTFLG_OrphanOnPolicyRemoval;
  1537. }
  1538. if (m_fMachine)
  1539. {
  1540. pii->dwActFlags |= ACTFLG_ForceUpgrade;
  1541. }
  1542. pii->InstallUiLevel = m_ToolDefaults.UILevel;
  1543. // disable MSI ui
  1544. MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
  1545. // Use MsiSummaryInfoGetProperty to get platform and locale info.
  1546. {
  1547. MSIHANDLE hSummaryInfo;
  1548. UINT msiReturn = MsiGetSummaryInformation(0, szPackagePath, 0, &hSummaryInfo);
  1549. if (ERROR_SUCCESS == msiReturn)
  1550. {
  1551. TCHAR szBuffer[256];
  1552. DWORD dwSize = 256;
  1553. msiReturn = MsiSummaryInfoGetProperty(hSummaryInfo,
  1554. 7, // PID_TEMPLATE
  1555. NULL,
  1556. NULL,
  1557. NULL,
  1558. szBuffer,
  1559. &dwSize);
  1560. if (ERROR_SUCCESS == msiReturn)
  1561. {
  1562. // break out the locale and platform properties
  1563. CString szLocales = szBuffer;
  1564. CString szPlatforms = szLocales.SpanExcluding(L";");
  1565. szLocales = szLocales.Mid(szPlatforms.GetLength()+1);
  1566. CString szTemp;
  1567. set<DWORD> sPlatforms;
  1568. BOOL fValidPlatform;
  1569. BOOL fPlatformsSpecified;
  1570. fValidPlatform = FALSE;
  1571. fPlatformsSpecified = 0 != szPlatforms.GetLength();
  1572. while (szPlatforms.GetLength())
  1573. {
  1574. szTemp = szPlatforms.SpanExcluding(L",");
  1575. if (0 == szTemp.CompareNoCase(L"intel"))
  1576. {
  1577. sPlatforms.insert(PROCESSOR_ARCHITECTURE_INTEL);
  1578. fValidPlatform = TRUE;
  1579. }
  1580. else if (0 == szTemp.CompareNoCase(L"amd64"))
  1581. {
  1582. sPlatforms.insert(PROCESSOR_ARCHITECTURE_AMD64);
  1583. fValidPlatform = TRUE;
  1584. }
  1585. else if (0 == szTemp.CompareNoCase(L"intel64"))
  1586. {
  1587. sPlatforms.insert(PROCESSOR_ARCHITECTURE_IA64);
  1588. fValidPlatform = TRUE;
  1589. }
  1590. szPlatforms = szPlatforms.Mid(szTemp.GetLength()+1);
  1591. }
  1592. //
  1593. // If platforms have been specified, at least one of them
  1594. // must be valid
  1595. //
  1596. if ( fPlatformsSpecified && ! fValidPlatform )
  1597. {
  1598. hr = HRESULT_FROM_WIN32( ERROR_INSTALL_PLATFORM_UNSUPPORTED );
  1599. ppi->cPlatforms = 0;
  1600. goto done;
  1601. }
  1602. while (szLocales.GetLength())
  1603. {
  1604. szTemp = szLocales.SpanExcluding(L",");
  1605. LCID lcid;
  1606. if (swscanf(szTemp, L"%i", &lcid) != EOF)
  1607. {
  1608. sLocales.insert(lcid);
  1609. szLocales = szLocales.Mid(szTemp.GetLength()+1);
  1610. }
  1611. }
  1612. if (0 == sPlatforms.size())
  1613. {
  1614. // If the MSI file doesn't specify an architecture
  1615. // then we'll mark it X86-allow on Win64.
  1616. sPlatforms.insert(PROCESSOR_ARCHITECTURE_INTEL);
  1617. pii->dwActFlags &= ~ACTFLG_ExcludeX86OnWin64;
  1618. DebugMsg((DL_VERBOSE, TEXT("No platform detected, setting to X86 - allow on Win64.")));
  1619. }
  1620. if (0 == sLocales.size())
  1621. {
  1622. // If the MSI file doesn't specify a locale then
  1623. // we'll just assume it's language neutral.
  1624. DebugMsg((DL_VERBOSE, TEXT("No locale detected, assuming neutral.")));
  1625. sLocales.insert(0);
  1626. }
  1627. ppi->cPlatforms = sPlatforms.size();
  1628. ppi->prgPlatform = (CSPLATFORM *) OLEALLOC(sizeof(CSPLATFORM) * (ppi->cPlatforms));;
  1629. if (!ppi->prgPlatform)
  1630. {
  1631. ppi->cPlatforms = 0;
  1632. goto out_of_memory;
  1633. }
  1634. set<DWORD>::iterator iPlatform;
  1635. INT n = 0;
  1636. for (iPlatform = sPlatforms.begin(); iPlatform != sPlatforms.end(); iPlatform++, n++)
  1637. {
  1638. ppi->prgPlatform[n].dwPlatformId = VER_PLATFORM_WIN32_NT;
  1639. ppi->prgPlatform[n].dwVersionHi = 5;
  1640. ppi->prgPlatform[n].dwVersionLo = 0;
  1641. ppi->prgPlatform[n].dwProcessorArch = *iPlatform;
  1642. }
  1643. }
  1644. MsiCloseHandle(hSummaryInfo);
  1645. }
  1646. if (ERROR_SUCCESS != msiReturn)
  1647. {
  1648. hr = HRESULT_FROM_WIN32(msiReturn);
  1649. LogADEEvent(EVENTLOG_ERROR_TYPE, EVENT_ADE_BADMSI_ERROR, hr, lpFileTitle);
  1650. goto done;
  1651. }
  1652. }
  1653. {
  1654. // Grovel through the database to get additional information
  1655. // that for some reason MSI won't give us any other way.
  1656. TCHAR szBuffer[256];
  1657. DWORD cch = 256;
  1658. UINT msiReturn = GetMsiProperty(szPackagePath, L"ProductVersion", szBuffer, &cch);
  1659. if (ERROR_SUCCESS != msiReturn)
  1660. {
  1661. hr = HRESULT_FROM_WIN32(msiReturn);
  1662. LogADEEvent(EVENTLOG_ERROR_TYPE, EVENT_ADE_BADMSI_ERROR, hr, lpFileTitle);
  1663. goto done;
  1664. }
  1665. if (ERROR_SUCCESS == msiReturn)
  1666. {
  1667. // Parse Product Version
  1668. CString sz = szBuffer;
  1669. sz.TrimLeft();
  1670. CString szTemp = sz.SpanIncluding(L"0123456789");
  1671. if (swscanf(szTemp, L"%u", &pii->dwVersionHi) == EOF)
  1672. {
  1673. hr = HRESULT_FROM_WIN32(GetLastError());
  1674. LogADEEvent(EVENTLOG_ERROR_TYPE, EVENT_ADE_BADMSI_ERROR, hr, lpFileTitle);
  1675. goto done;
  1676. }
  1677. sz = sz.Mid(szTemp.GetLength());
  1678. szTemp = sz.SpanExcluding(L"0123456789");
  1679. sz = sz.Mid(szTemp.GetLength());
  1680. if (swscanf(sz, L"%u", &pii->dwVersionLo) == EOF)
  1681. {
  1682. hr = HRESULT_FROM_WIN32(GetLastError());
  1683. LogADEEvent(EVENTLOG_ERROR_TYPE, EVENT_ADE_BADMSI_ERROR, hr, lpFileTitle);
  1684. goto done;
  1685. }
  1686. }
  1687. cch = 256;
  1688. msiReturn = GetMsiProperty(szPackagePath, L"ProductCode", szBuffer, &cch);
  1689. if (ERROR_SUCCESS != msiReturn)
  1690. {
  1691. hr = HRESULT_FROM_WIN32(msiReturn);
  1692. LogADEEvent(EVENTLOG_ERROR_TYPE, EVENT_ADE_BADMSI_ERROR, hr, lpFileTitle);
  1693. goto done;
  1694. }
  1695. if (ERROR_SUCCESS == msiReturn)
  1696. {
  1697. // Parse Product Code
  1698. CLSIDFromString(szBuffer, &pii->ProductCode);
  1699. }
  1700. cch = 256;
  1701. msiReturn = GetMsiProperty(szPackagePath, L"ARPHELPLINK", szBuffer, &cch);
  1702. if (ERROR_SUCCESS == msiReturn)
  1703. {
  1704. OLESAFE_COPYSTRING(pii->pszUrl, szBuffer);
  1705. }
  1706. cch = 256;
  1707. msiReturn = GetMsiProperty(szPackagePath, L"LIMITUI", szBuffer, &cch);
  1708. if (ERROR_SUCCESS == msiReturn)
  1709. {
  1710. pii->dwActFlags |= ACTFLG_MinimalInstallUI;
  1711. pii->InstallUiLevel = INSTALLUILEVEL_BASIC;
  1712. }
  1713. }
  1714. ppi->prgLocale = (LCID *) OLEALLOC(sizeof(LCID));
  1715. if (!ppi->prgLocale)
  1716. {
  1717. goto out_of_memory;
  1718. }
  1719. ppi->cLocales = 1;
  1720. ppd->pszSourceList = (LPOLESTR *) OLEALLOC(sizeof(LPOLESTR));
  1721. if (!ppd->pszSourceList)
  1722. {
  1723. goto out_of_memory;
  1724. }
  1725. ppd->cSources = 1;
  1726. OLESAFE_COPYSTRING(ppd->pszSourceList[0], szPackagePath);
  1727. if (S_OK == DetectUpgrades(szPackagePath, ppd, dlgUpgrade))
  1728. {
  1729. UINT n = dlgUpgrade.m_UpgradeList.size();
  1730. if (n)
  1731. {
  1732. pii->prgUpgradeInfoList = (UPGRADEINFO *) OLEALLOC(sizeof(UPGRADEINFO) * n);
  1733. if (!pii->prgUpgradeInfoList)
  1734. {
  1735. goto out_of_memory;
  1736. }
  1737. pii->cUpgrades = n;
  1738. map<CString, CUpgradeData>::iterator i = dlgUpgrade.m_UpgradeList.begin();
  1739. while (n--)
  1740. {
  1741. pii->prgUpgradeInfoList[n].Flag = i->second.m_flags;
  1742. OLESAFE_COPYSTRING(pii->prgUpgradeInfoList[n].szClassStore, i->second.m_szClassStore);
  1743. memcpy(&pii->prgUpgradeInfoList[n].PackageGuid, &i->second.m_PackageGuid, sizeof(GUID));
  1744. i++;
  1745. }
  1746. }
  1747. }
  1748. //
  1749. // Only one locale may be specified for this package
  1750. //
  1751. nLocales = 1;
  1752. iLocale = sLocales.begin();
  1753. {
  1754. ppi->prgLocale[0] = *iLocale;
  1755. // set the script path
  1756. hr = CoCreateGuid(&guid);
  1757. if (FAILED(hr))
  1758. {
  1759. goto done;
  1760. }
  1761. OLECHAR sz [256];
  1762. StringFromGUID2(guid, sz, 256);
  1763. CString szScriptPath = m_szGPT_Path;
  1764. szScriptPath += L"\\";
  1765. szScriptPath += sz;
  1766. szScriptPath += L".aas";
  1767. OLESAFE_DELETE(pii->pszScriptPath);
  1768. OLESAFE_COPYSTRING(pii->pszScriptPath, szScriptPath);
  1769. HWND hwnd;
  1770. m_pConsole->GetMainWindow(&hwnd);
  1771. hr = BuildScriptAndGetActInfo(*ppd, m_ToolDefaults.fExtensionsOnly);
  1772. // make sure the name is unique
  1773. szFriendlyName = ppd->pszPackageName;
  1774. GetUniquePackageName(szFriendlyName, szUniqueFriendlyName, nHint);
  1775. OLESAFE_DELETE(ppd->pszPackageName);
  1776. OLESAFE_COPYSTRING(ppd->pszPackageName, szUniqueFriendlyName);
  1777. if (SUCCEEDED(hr))
  1778. {
  1779. fPreparationDone = TRUE;
  1780. do
  1781. {
  1782. hr = DeployPackage(ppd, fShowPropertySheet);
  1783. if (hr == CS_E_OBJECT_ALREADY_EXISTS)
  1784. {
  1785. GetUniquePackageName(szFriendlyName, szUniqueFriendlyName, nHint);
  1786. OLESAFE_DELETE(ppd->pszPackageName);
  1787. OLESAFE_COPYSTRING(ppd->pszPackageName, szUniqueFriendlyName);
  1788. }
  1789. } while (hr == CS_E_OBJECT_ALREADY_EXISTS);
  1790. }
  1791. if (FAILED(hr))
  1792. {
  1793. // clean up script file if deployment fails
  1794. DeleteFile(pii->pszScriptPath);
  1795. }
  1796. }
  1797. done:
  1798. if (FAILED(hr) && hr != E_FAIL) // don't report E_FAIL error
  1799. // because it's a benign error
  1800. // (probably a dialog cancellation)
  1801. {
  1802. // report the error in the event log
  1803. LogADEEvent(EVENTLOG_ERROR_TYPE, EVENT_ADE_DEPLOYMENT_ERROR, hr, lpFileTitle);
  1804. TCHAR szBuffer[256];
  1805. if (HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED) == hr)
  1806. {
  1807. // access permission failure
  1808. ::LoadString(ghInstance, IDS_ADDFAILED_ACCESS_DENIED, szBuffer, 256);
  1809. }
  1810. else if ( HRESULT_FROM_WIN32( ERROR_INSTALL_PLATFORM_UNSUPPORTED ) == hr )
  1811. {
  1812. ::LoadString(ghInstance, IDS_ILLEGAL_PLATFORM, szBuffer, 256);
  1813. }
  1814. else if ( HRESULT_FROM_WIN32( CS_E_ADMIN_LIMIT_EXCEEDED ) == hr )
  1815. {
  1816. ::LoadString(ghInstance, IDS_ADDFAILED_METADATA_OVERFLOW, szBuffer, 256);
  1817. }
  1818. else
  1819. {
  1820. if (fPreparationDone)
  1821. {
  1822. switch (hr)
  1823. {
  1824. // For these errors, we'll report the party line:
  1825. case CS_E_CLASS_NOTFOUND:
  1826. case CS_E_INVALID_VERSION:
  1827. case CS_E_NO_CLASSSTORE:
  1828. case CS_E_OBJECT_NOTFOUND:
  1829. case CS_E_OBJECT_ALREADY_EXISTS:
  1830. case CS_E_INVALID_PATH:
  1831. case CS_E_NETWORK_ERROR:
  1832. case CS_E_SCHEMA_MISMATCH:
  1833. case CS_E_PACKAGE_NOTFOUND:
  1834. case CS_E_INTERNAL_ERROR:
  1835. {
  1836. DWORD dw = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
  1837. NULL,
  1838. hr,
  1839. 0,
  1840. szBuffer,
  1841. sizeof(szBuffer) / sizeof(szBuffer[0]),
  1842. NULL);
  1843. if (0 != dw)
  1844. {
  1845. // got a valid message string
  1846. break;
  1847. }
  1848. // otherwise fall through and give the generic message
  1849. }
  1850. // Either these CS errors don't apply or an admin
  1851. // wouldn't know what they mean:
  1852. case CS_E_NOT_DELETABLE:
  1853. default:
  1854. // generic class store problem
  1855. ::LoadString(ghInstance, IDS_ADDFAILED_CSFAILURE, szBuffer, 256);
  1856. break;
  1857. }
  1858. }
  1859. else
  1860. {
  1861. // probably some error with the package itself
  1862. ::LoadString(ghInstance, IDS_ADDFAILED, szBuffer, 256);
  1863. }
  1864. }
  1865. #if DBG
  1866. TCHAR szDebugBuffer[256];
  1867. DWORD dw = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
  1868. NULL,
  1869. hr,
  1870. 0,
  1871. szDebugBuffer,
  1872. sizeof(szDebugBuffer) / sizeof(szDebugBuffer[0]),
  1873. NULL);
  1874. if (0 == dw)
  1875. {
  1876. (void) StringCchPrintf(szDebugBuffer,
  1877. sizeof(szDebugBuffer)/sizeof(szDebugBuffer[0]),
  1878. TEXT("(HRESULT: 0x%lX)"),
  1879. hr);
  1880. }
  1881. (void) StringCchCat(szBuffer,
  1882. sizeof(szBuffer) / sizeof(szBuffer[0]),
  1883. szDebugBuffer);
  1884. #endif
  1885. m_pConsole->MessageBox(szBuffer,
  1886. lpFileTitle,
  1887. MB_OK | MB_ICONEXCLAMATION, NULL);
  1888. }
  1889. InternalFreePackageDetail(ppd);
  1890. delete ppd;
  1891. }
  1892. }
  1893. return hr;
  1894. out_of_memory:
  1895. if (ppd)
  1896. {
  1897. LogADEEvent(EVENTLOG_ERROR_TYPE, EVENT_ADE_GENERAL_ERROR, E_OUTOFMEMORY);
  1898. InternalFreePackageDetail(ppd);
  1899. delete ppd;
  1900. }
  1901. return E_OUTOFMEMORY;
  1902. }
  1903. //+--------------------------------------------------------------------------
  1904. //
  1905. // Member: CScopePane::DetectUpgrades
  1906. //
  1907. // Synopsis: This functions checks if any of the existing packages in the
  1908. // class store can be upgraded by a given package. If any such
  1909. // packages exist, then this function populates the m_UpgradeList
  1910. // member of the dlgUpgrade parameter passed to it. This function
  1911. // also adds the upgrade code GUID to the PACKAGEDETAIL structure
  1912. // passed to it.
  1913. //
  1914. // Arguments:
  1915. // szPackagePath - the path of the given package
  1916. // ppd - pointer to the PACKAGEDETAIL structure of the
  1917. // given package
  1918. // dlgUpgrade - the dialog whose member m_UpgradeList needs to be
  1919. // populated
  1920. //
  1921. // Returns:
  1922. // S_OK the function succeeded in finding upgradeable packages
  1923. // S_FALSE the function did not encounter any errors, but no
  1924. // upgradeable packages were found
  1925. // other failure codes the function encountered errors
  1926. //
  1927. // History: 5/19/1998 RahulTh created
  1928. //
  1929. // Notes:
  1930. //
  1931. //---------------------------------------------------------------------------
  1932. HRESULT CScopePane::DetectUpgrades (LPCOLESTR szPackagePath, const PACKAGEDETAIL* ppd, CUpgrades& dlgUpgrade)
  1933. {
  1934. DWORD dwBufSize = 50;
  1935. TCHAR szUpgradeCode[50]; //the upgrade GUID
  1936. GUID guidUpgradeCode;
  1937. TCHAR szData[50];
  1938. DWORD dwOperator;
  1939. HRESULT hr;
  1940. HRESULT hres;
  1941. MSIHANDLE hDatabase;
  1942. UINT msiReturn;
  1943. map<MMC_COOKIE, CAppData>::iterator i;
  1944. INSTALLINFO* pii;
  1945. BOOL fUpgradeable;
  1946. LARGE_INTEGER verNew, verExisting;
  1947. CString szCSPath;
  1948. hr = GetClassStoreName(szCSPath, FALSE);
  1949. if (FAILED(hr))
  1950. {
  1951. DebugMsg((DM_WARNING, TEXT("GetClassStoreName failed with 0x%x"), hr));
  1952. }
  1953. msiReturn = GetMsiProperty(szPackagePath, TEXT("UpgradeCode"), szUpgradeCode, &dwBufSize);
  1954. if (ERROR_SUCCESS != msiReturn)
  1955. return HRESULT_FROM_WIN32(msiReturn); //no upgrade code was found
  1956. hr = CLSIDFromString(szUpgradeCode, &guidUpgradeCode);
  1957. if (FAILED(hr))
  1958. return hr;
  1959. //insert the upgrade code GUID into the packagedetail structure.
  1960. memcpy((LPVOID)&(ppd->pInstallInfo->Mvipc), (LPVOID)&guidUpgradeCode, sizeof(GUID));
  1961. verNew.LowPart = ppd->pInstallInfo->dwVersionLo;
  1962. verNew.HighPart = ppd->pInstallInfo->dwVersionHi;
  1963. hr = S_FALSE; //this will get set to S_OK only if we find any upgradeable packages
  1964. msiReturn = MsiOpenDatabase (szPackagePath, MSIDBOPEN_READONLY, &hDatabase);
  1965. if (ERROR_SUCCESS == msiReturn)
  1966. {
  1967. CString szQuery;
  1968. szQuery.Format (TEXT("SELECT `UpgradeCode`, `Attributes`, `VersionMin`, `VersionMax`, `Language` FROM `Upgrade`"));
  1969. MSIHANDLE hView;
  1970. msiReturn = MsiDatabaseOpenView(hDatabase, szQuery, &hView);
  1971. if (ERROR_SUCCESS == msiReturn)
  1972. {
  1973. msiReturn = MsiViewExecute (hView, 0);
  1974. if (ERROR_SUCCESS == msiReturn)
  1975. {
  1976. MSIHANDLE hRecord;
  1977. //for each operator value returned by the query, if an operator is found that permits
  1978. //upgrades, iterate through the list of existing packages to see if any of those are
  1979. //upgradeable by the supplied package. If any such package is found, add it to the
  1980. //m_UpgradeList member of the upgrade dialog dlgUpgrade.
  1981. do
  1982. {
  1983. msiReturn = MsiViewFetch (hView, &hRecord);
  1984. if (ERROR_SUCCESS == msiReturn)
  1985. {
  1986. //reset dwBufSize since it is modified by MsiRecordString during every iteration
  1987. //of the loop.
  1988. dwBufSize = 50;
  1989. //get the upgrade code for this upgrade table entry
  1990. msiReturn = MsiRecordGetString (hRecord, 1, szData, &dwBufSize);
  1991. hres = CLSIDFromString (szData, &guidUpgradeCode);
  1992. if (FAILED(hres))
  1993. {
  1994. MsiCloseHandle(hRecord);
  1995. continue; //ignore this package and move on to the next
  1996. }
  1997. dwBufSize = 50; //must reset to reflect the correct buffer size
  1998. //get the operator for this upgrade table entry
  1999. msiReturn = MsiRecordGetString (hRecord, 2, szData, &dwBufSize);
  2000. int iRetVal;
  2001. iRetVal = swscanf(szData, TEXT("%d"), &dwOperator);
  2002. if ((iRetVal != EOF) && (0 == (dwOperator & 0x002)))
  2003. {
  2004. // we have a potential hit
  2005. LARGE_INTEGER verMin;
  2006. LARGE_INTEGER verMax;
  2007. // get min version
  2008. dwBufSize = 50; //must reset to reflect the correct buffer size
  2009. BOOL fMin = FALSE;
  2010. msiReturn = MsiRecordGetString (hRecord, 3, szData, &dwBufSize);
  2011. if (ERROR_SUCCESS == msiReturn && 0 != szData[0])
  2012. {
  2013. fMin = TRUE;
  2014. // Parse Product Version
  2015. CString sz = szData;
  2016. sz.TrimLeft();
  2017. CString szTemp = sz.SpanIncluding(L"0123456789");
  2018. if (swscanf(szTemp, L"%u", &verMin.HighPart) != EOF)
  2019. {
  2020. sz = sz.Mid(szTemp.GetLength());
  2021. szTemp = sz.SpanExcluding(L"0123456789");
  2022. sz = sz.Mid(szTemp.GetLength());
  2023. if (swscanf(sz, L"%u", &verMin.LowPart) == EOF)
  2024. {
  2025. LogADEEvent(EVENTLOG_WARNING_TYPE, EVENT_ADE_UNEXPECTEDMSI_ERROR, HRESULT_FROM_WIN32(GetLastError()), szPackagePath);
  2026. }
  2027. }
  2028. else
  2029. {
  2030. LogADEEvent(EVENTLOG_WARNING_TYPE, EVENT_ADE_UNEXPECTEDMSI_ERROR, HRESULT_FROM_WIN32(GetLastError()), szPackagePath);
  2031. }
  2032. }
  2033. else
  2034. {
  2035. LogADEEvent(EVENTLOG_WARNING_TYPE, EVENT_ADE_UNEXPECTEDMSI_ERROR, HRESULT_FROM_WIN32(msiReturn), szPackagePath);
  2036. }
  2037. // get max version
  2038. dwBufSize = 50; //must reset to reflect the correct buffer size
  2039. BOOL fMax = FALSE;
  2040. msiReturn = MsiRecordGetString (hRecord, 4, szData, &dwBufSize);
  2041. if (ERROR_SUCCESS == msiReturn && 0 != szData[0])
  2042. {
  2043. fMax = TRUE;
  2044. // Parse Product Version
  2045. CString sz = szData;
  2046. sz.TrimLeft();
  2047. CString szTemp = sz.SpanIncluding(L"0123456789");
  2048. if (swscanf(szTemp, L"%u", &verMax.HighPart) != EOF)
  2049. {
  2050. sz = sz.Mid(szTemp.GetLength());
  2051. szTemp = sz.SpanExcluding(L"0123456789");
  2052. sz = sz.Mid(szTemp.GetLength());
  2053. if (swscanf(sz, L"%u", &verMax.LowPart) == EOF)
  2054. {
  2055. LogADEEvent(EVENTLOG_WARNING_TYPE, EVENT_ADE_UNEXPECTEDMSI_ERROR, HRESULT_FROM_WIN32(GetLastError()), szPackagePath);
  2056. }
  2057. }
  2058. else
  2059. {
  2060. LogADEEvent(EVENTLOG_WARNING_TYPE, EVENT_ADE_UNEXPECTEDMSI_ERROR, HRESULT_FROM_WIN32(GetLastError()), szPackagePath);
  2061. }
  2062. }
  2063. else
  2064. {
  2065. LogADEEvent(EVENTLOG_WARNING_TYPE, EVENT_ADE_UNEXPECTEDMSI_ERROR, HRESULT_FROM_WIN32(msiReturn), szPackagePath);
  2066. }
  2067. // get lcid list
  2068. dwBufSize = 0; //must reset to reflect the correct buffer size
  2069. BOOL fLcids = FALSE;
  2070. set<LCID> sLCID;
  2071. msiReturn = MsiRecordGetString (hRecord, 5, szData, &dwBufSize);
  2072. if (ERROR_MORE_DATA == msiReturn)
  2073. {
  2074. dwBufSize++;
  2075. TCHAR * szLanguages = new TCHAR[dwBufSize];
  2076. if (szLanguages)
  2077. {
  2078. msiReturn = MsiRecordGetString (hRecord, 5, szLanguages, &dwBufSize);
  2079. if (ERROR_SUCCESS == msiReturn)
  2080. {
  2081. // build set of LCIDs
  2082. CString sz = szLanguages;
  2083. sz.TrimLeft();
  2084. while (!sz.IsEmpty())
  2085. {
  2086. fLcids = TRUE;
  2087. LCID lcid;
  2088. CString szTemp = sz.SpanIncluding(L"0123456789");
  2089. if (swscanf(szTemp, L"%u", &lcid) != EOF)
  2090. {
  2091. sz = sz.Mid(szTemp.GetLength());
  2092. szTemp = sz.SpanExcluding(L"0123456789");
  2093. sz = sz.Mid(szTemp.GetLength());
  2094. sLCID.insert(lcid);
  2095. }
  2096. else
  2097. {
  2098. LogADEEvent(EVENTLOG_WARNING_TYPE, EVENT_ADE_UNEXPECTEDMSI_ERROR, HRESULT_FROM_WIN32(GetLastError()), szPackagePath);
  2099. }
  2100. }
  2101. }
  2102. else
  2103. {
  2104. LogADEEvent(EVENTLOG_WARNING_TYPE, EVENT_ADE_UNEXPECTEDMSI_ERROR, HRESULT_FROM_WIN32(msiReturn), szPackagePath);
  2105. }
  2106. delete [] szLanguages;
  2107. }
  2108. }
  2109. else
  2110. {
  2111. LogADEEvent(EVENTLOG_WARNING_TYPE, EVENT_ADE_UNEXPECTEDMSI_ERROR, HRESULT_FROM_WIN32(msiReturn), szPackagePath);
  2112. }
  2113. //if an operator is found that that does not block installs and
  2114. //does not force uninstalling of existing apps, then search
  2115. //for any packages that can be upgraded
  2116. for (i = m_AppData.begin(); i != m_AppData.end(); i++)
  2117. {
  2118. //get the install info. for the app.
  2119. pii = (i->second.m_pDetails)->pInstallInfo;
  2120. //process this only if it has the same upgrade code
  2121. if ( (guidUpgradeCode == pii->Mvipc) && ! IsNullGUID(&guidUpgradeCode) )
  2122. {
  2123. //check if other conditions for the operator are satisfied.
  2124. verExisting.LowPart = pii->dwVersionLo;
  2125. verExisting.HighPart = pii->dwVersionHi;
  2126. // don't even bother to upgrade unless the
  2127. // new version is greater or equal to the
  2128. // old version
  2129. fUpgradeable = (verNew.QuadPart >= verExisting.QuadPart);
  2130. if (fMin && fUpgradeable)
  2131. {
  2132. // check minimum
  2133. if (0 != (dwOperator & 0x100))
  2134. {
  2135. // inclusive
  2136. fUpgradeable = verExisting.QuadPart >= verMin.QuadPart;
  2137. }
  2138. else
  2139. {
  2140. // exclusive
  2141. fUpgradeable = verExisting.QuadPart > verMin.QuadPart;
  2142. }
  2143. }
  2144. if (fMax && fUpgradeable)
  2145. {
  2146. // check maximum
  2147. if (0 != (dwOperator & 0x200))
  2148. {
  2149. // inclusive
  2150. fUpgradeable = verExisting.QuadPart <= verMax.QuadPart;
  2151. }
  2152. else
  2153. {
  2154. // exclusive
  2155. fUpgradeable = verExisting.QuadPart < verMax.QuadPart;
  2156. }
  2157. }
  2158. if (fLcids && fUpgradeable)
  2159. {
  2160. // check the lcid
  2161. BOOL fMatch = FALSE;
  2162. // look for a match
  2163. PLATFORMINFO * ppi = (i->second.m_pDetails)->pPlatformInfo;
  2164. UINT n = ppi->cLocales;
  2165. while ((n--) && !fMatch)
  2166. {
  2167. if (sLCID.end() != sLCID.find(ppi->prgLocale[n]))
  2168. {
  2169. fMatch = TRUE;
  2170. }
  2171. }
  2172. // set the upgradeable flag
  2173. if (0 != (dwOperator & 0x400))
  2174. {
  2175. // exclusive
  2176. fUpgradeable = !fMatch;
  2177. }
  2178. else
  2179. {
  2180. // inclusive
  2181. fUpgradeable = fMatch;
  2182. }
  2183. }
  2184. if (fUpgradeable) //the package in question can be upgraded
  2185. {
  2186. CUpgradeData data;
  2187. data.m_szClassStore = szCSPath;
  2188. memcpy(&data.m_PackageGuid, &pii->PackageGuid, sizeof(GUID));
  2189. data.m_flags = UPGFLG_NoUninstall | UPGFLG_Enforced;
  2190. dlgUpgrade.m_UpgradeList.insert(pair<const CString, CUpgradeData>(GetUpgradeIndex(data.m_PackageGuid), data));
  2191. hr = S_OK;
  2192. }
  2193. }
  2194. }
  2195. }
  2196. MsiCloseHandle(hRecord);
  2197. }
  2198. } while (NULL != hRecord && ERROR_SUCCESS == msiReturn);
  2199. MsiViewClose (hView); //close the view to be on the safe side, though it is not absolutely essential
  2200. }
  2201. else
  2202. hr = HRESULT_FROM_WIN32(msiReturn);
  2203. MsiCloseHandle(hView);
  2204. }
  2205. else
  2206. hr = HRESULT_FROM_WIN32(msiReturn);
  2207. MsiCloseHandle (hDatabase);
  2208. }
  2209. else
  2210. hr = HRESULT_FROM_WIN32(msiReturn);
  2211. if (FAILED(hr))
  2212. {
  2213. if (msiReturn != ERROR_SUCCESS)
  2214. {
  2215. LogADEEvent(EVENTLOG_ERROR_TYPE, EVENT_ADE_BADMSI_ERROR, hr, szPackagePath);
  2216. }
  2217. else
  2218. {
  2219. LogADEEvent(EVENTLOG_ERROR_TYPE, EVENT_ADE_GENERAL_ERROR, hr);
  2220. }
  2221. }
  2222. return hr;
  2223. }
  2224. //+--------------------------------------------------------------------------
  2225. //
  2226. // Member: CScopePane::DisplayPropSheet
  2227. //
  2228. // Synopsis: a generic routine for showing the property sheet for a package
  2229. //
  2230. // Arguments: [szPackeName] - name of the package to show properties for
  2231. // [iPage] - index of the preferred page to display
  2232. //
  2233. // Returns: nothing
  2234. //
  2235. // History: 3-11-1998 stevebl Created
  2236. //
  2237. // Notes: The property sheet will be started on the preferred page
  2238. // only if it isn't already being displayed, in which case
  2239. // whatever page was being displayed will retain the focus.
  2240. //
  2241. //---------------------------------------------------------------------------
  2242. void CScopePane::DisplayPropSheet(CString szPackageName, int iPage)
  2243. {
  2244. map <MMC_COOKIE, CAppData>::iterator i = m_AppData.begin();
  2245. while (i != m_AppData.end())
  2246. {
  2247. if (0 == szPackageName.Compare(i->second.m_pDetails->pszPackageName))
  2248. {
  2249. IDataObject * pDataObject;
  2250. HRESULT hr = QueryDataObject(i->first, CCT_RESULT, &pDataObject);
  2251. if (SUCCEEDED(hr))
  2252. {
  2253. set <CResultPane *>::iterator i2;
  2254. for (i2 = m_sResultPane.begin(); i2 != m_sResultPane.end(); i2++)
  2255. {
  2256. hr = m_pIPropertySheetProvider->FindPropertySheet(i->first, (*i2), pDataObject);
  2257. if (S_FALSE == hr)
  2258. {
  2259. m_pIPropertySheetProvider->CreatePropertySheet(i->second.m_pDetails->pszPackageName, TRUE, i->first, pDataObject, 0);
  2260. m_pIPropertySheetProvider->AddPrimaryPages((*i2)->GetUnknown(), FALSE, NULL, FALSE);
  2261. m_pIPropertySheetProvider->AddExtensionPages();
  2262. m_pIPropertySheetProvider->Show(NULL, iPage);
  2263. }
  2264. }
  2265. }
  2266. return;
  2267. }
  2268. i++;
  2269. }
  2270. }
  2271. //+--------------------------------------------------------------------------
  2272. //
  2273. // Member: CScopePane::RemovePackage
  2274. //
  2275. // Synopsis: Removes a package from the class store and the result pane.
  2276. //
  2277. // Arguments: [pDataObject] - data object for this result pane item
  2278. // [fForceUninstall] - TRUE - force app to be uninstalled on
  2279. // client machines
  2280. // FALSE - orphan any installations
  2281. //
  2282. // Returns: S_OK - success
  2283. //
  2284. // History: 2-03-1998 stevebl Created
  2285. // 3-30-1998 stevebl adde fForceUninstall
  2286. //
  2287. // Notes: bAssigned is used
  2288. //
  2289. //---------------------------------------------------------------------------
  2290. HRESULT CScopePane::RemovePackage(MMC_COOKIE cookie, BOOL fForceUninstall, BOOL fRemoveNow)
  2291. {
  2292. BOOL fAssigned;
  2293. HRESULT hr = E_FAIL;
  2294. // put up an hourglass (this could take a while)
  2295. CHourglass hourglass;
  2296. CAppData & data = m_AppData[cookie];
  2297. CString szPackageName = data.m_pDetails->pszPackageName;
  2298. // We are now not removing script files here; instead the script
  2299. // file will be removed by the class store code when the package
  2300. // is actually removed from the DS.
  2301. #if 0
  2302. // only remove script files for packages that have script files
  2303. if (data.m_pDetails->pInstallInfo->PathType == DrwFilePath)
  2304. {
  2305. // We need to make sure it gets removed from
  2306. // the GPT before we delete it from the class store.
  2307. // check to see if it's an old style relative path
  2308. if (L'\\' != data.m_pDetails->pInstallInfo->pszScriptPath[0])
  2309. {
  2310. // find the last element in the path
  2311. int iBreak = m_szGPT_Path.ReverseFind(L'{');
  2312. CString sz = m_szGPT_Path.Left(iBreak-1);
  2313. sz += L"\\";
  2314. sz += data.m_pDetails->pInstallInfo->pszScriptPath;
  2315. DeleteFile(sz);
  2316. }
  2317. else
  2318. DeleteFile(data.m_pDetails->pInstallInfo->pszScriptPath);
  2319. }
  2320. #endif
  2321. if (0 != (data.m_pDetails->pInstallInfo->dwActFlags & ACTFLG_Assigned))
  2322. {
  2323. fAssigned = TRUE;
  2324. }
  2325. else
  2326. {
  2327. fAssigned = FALSE;
  2328. }
  2329. hr = m_pIClassAdmin->RemovePackage((LPOLESTR)((LPCOLESTR)(data.m_pDetails->pszPackageName)),
  2330. fRemoveNow ? 0 :
  2331. ((fForceUninstall ? ACTFLG_Uninstall : ACTFLG_Orphan) |
  2332. (data.m_pDetails->pInstallInfo->dwActFlags &
  2333. (ACTFLG_ExcludeX86OnWin64 | ACTFLG_IgnoreLanguage))) );
  2334. if (SUCCEEDED(hr))
  2335. {
  2336. // Notify clients of change
  2337. if (FAILED(m_pIGPEInformation->PolicyChanged(m_fMachine, TRUE, &guidExtension,
  2338. m_fMachine ? &guidMachSnapin
  2339. : &guidUserSnapin)))
  2340. {
  2341. ReportPolicyChangedError(m_hwndMainWindow);
  2342. }
  2343. #if 0
  2344. if (data.m_fVisible)
  2345. {
  2346. set <CResultPane *>::iterator i;
  2347. for (i = m_sResultPane.begin(); i != m_sResultPane.end(); i++)
  2348. {
  2349. (*i)->m_pResult->DeleteItem(data.m_itemID, 0);
  2350. }
  2351. }
  2352. if (SUCCEEDED(hr))
  2353. {
  2354. CString szCSPath;
  2355. hr = GetClassStoreName(szCSPath, FALSE);
  2356. if (FAILED(hr))
  2357. {
  2358. DebugMsg((DM_WARNING, TEXT("GetClassStoreName failed with 0x%x"), hr));
  2359. }
  2360. // remove its entries in the extension table
  2361. RemoveExtensionEntry(cookie, data);
  2362. if (m_pFileExt)
  2363. {
  2364. m_pFileExt->SendMessage(WM_USER_REFRESH, 0, 0);
  2365. }
  2366. RemoveUpgradeEntry(cookie, data);
  2367. m_UpgradeIndex.erase(GetUpgradeIndex(data.m_pDetails->pInstallInfo->PackageGuid));
  2368. // If this thing upgraded other apps or had apps that were
  2369. // upgrading, make sure that they get the proper icons and any
  2370. // property sheets get updated.
  2371. UINT n = data.m_pDetails->pInstallInfo->cUpgrades;
  2372. while (n--)
  2373. {
  2374. map<CString, MMC_COOKIE>::iterator i = m_UpgradeIndex.find(GetUpgradeIndex(data.m_pDetails->pInstallInfo->prgUpgradeInfoList[n].PackageGuid));
  2375. if (i != m_UpgradeIndex.end())
  2376. {
  2377. RESULTDATAITEM rd;
  2378. memset(&rd, 0, sizeof(rd));
  2379. rd.mask = RDI_IMAGE;
  2380. rd.itemID = m_AppData[i->second].m_itemID;
  2381. rd.nImage = m_AppData[i->second].GetImageIndex(this);
  2382. set <CResultPane *>::iterator i2;
  2383. for (i2 = m_sResultPane.begin(); i2 != m_sResultPane.end(); i2++)
  2384. {
  2385. (*i2)->m_pResult->SetItem(&rd);
  2386. }
  2387. if (m_AppData[i->second].m_pUpgradeList)
  2388. {
  2389. m_AppData[i->second].m_pUpgradeList->SendMessage(WM_USER_REFRESH, 0, 0);
  2390. }
  2391. }
  2392. }
  2393. FreePackageDetail(data.m_pDetails);
  2394. m_AppData.erase(cookie);
  2395. set <CResultPane *>::iterator i;
  2396. for (i = m_sResultPane.begin(); i != m_sResultPane.end(); i++)
  2397. {
  2398. (*i)->m_pResult->Sort((*i)->m_nSortColumn, (*i)->m_dwSortOptions, -1);
  2399. }
  2400. }
  2401. #else
  2402. // just force a refresh
  2403. Refresh();
  2404. }
  2405. #endif
  2406. else
  2407. {
  2408. DebugMsg((DM_WARNING, TEXT("RemovePackage failed with 0x%x"), hr));
  2409. }
  2410. if (FAILED(hr) && hr != E_FAIL) // don't report E_FAIL error
  2411. {
  2412. LogADEEvent(EVENTLOG_ERROR_TYPE, EVENT_ADE_REMOVE_ERROR, hr, data.m_pDetails->pszPackageName);
  2413. TCHAR szBuffer[256];
  2414. if (HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED) == hr)
  2415. {
  2416. // access permission failure
  2417. ::LoadString(ghInstance, IDS_DELFAILED_ACCESS_DENIED, szBuffer, 256);
  2418. }
  2419. else
  2420. {
  2421. switch (hr)
  2422. {
  2423. // For these errors, we'll report the party line:
  2424. case CS_E_CLASS_NOTFOUND:
  2425. case CS_E_INVALID_VERSION:
  2426. case CS_E_NO_CLASSSTORE:
  2427. case CS_E_OBJECT_NOTFOUND:
  2428. case CS_E_OBJECT_ALREADY_EXISTS:
  2429. case CS_E_INVALID_PATH:
  2430. case CS_E_NETWORK_ERROR:
  2431. case CS_E_ADMIN_LIMIT_EXCEEDED:
  2432. case CS_E_SCHEMA_MISMATCH:
  2433. case CS_E_PACKAGE_NOTFOUND:
  2434. case CS_E_INTERNAL_ERROR:
  2435. case CS_E_NOT_DELETABLE:
  2436. {
  2437. DWORD dw = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
  2438. NULL,
  2439. hr,
  2440. 0,
  2441. szBuffer,
  2442. sizeof(szBuffer) / sizeof(szBuffer[0]),
  2443. NULL);
  2444. if (0 != dw)
  2445. {
  2446. // got a valid message string
  2447. break;
  2448. }
  2449. // otherwise fall through and give the generic message
  2450. }
  2451. // Either these CS errors don't apply or an admin
  2452. // wouldn't know what they mean:
  2453. default:
  2454. // generic class store problem
  2455. ::LoadString(ghInstance, IDS_DELFAILED_CSFAILURE, szBuffer, 256);
  2456. break;
  2457. }
  2458. }
  2459. #if DBG
  2460. TCHAR szDebugBuffer[256];
  2461. DWORD dw = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
  2462. NULL,
  2463. hr,
  2464. 0,
  2465. szDebugBuffer,
  2466. sizeof(szDebugBuffer) / sizeof(szDebugBuffer[0]),
  2467. NULL);
  2468. if (0 == dw)
  2469. {
  2470. (void) StringCchPrintf(szDebugBuffer,
  2471. sizeof(szDebugBuffer)/sizeof(szDebugBuffer[0]),
  2472. TEXT("(HRESULT: 0x%lX)"),
  2473. hr);
  2474. }
  2475. (void) StringCchCat(szBuffer,
  2476. sizeof(szBuffer) / sizeof(szBuffer[0]),
  2477. szDebugBuffer);
  2478. #endif
  2479. m_pConsole->MessageBox(szBuffer,
  2480. szPackageName,
  2481. MB_OK | MB_ICONEXCLAMATION, NULL);
  2482. }
  2483. return hr;
  2484. }
  2485. //+--------------------------------------------------------------------------
  2486. //
  2487. // Member: CScopePane::PopulateUpgradeLists
  2488. //
  2489. // Synopsis: Walks the list of apps, making sure that all the upgrade
  2490. // tables are complete.
  2491. //
  2492. // Arguments: none
  2493. //
  2494. // Returns:
  2495. //
  2496. // History: 2-02-1998 stevebl Created
  2497. //
  2498. //---------------------------------------------------------------------------
  2499. HRESULT CScopePane::PopulateUpgradeLists()
  2500. {
  2501. HRESULT hr = S_OK;
  2502. // For each app in the list, insert an entry in the upgrade tables of
  2503. // the apps it upgrades.
  2504. map <MMC_COOKIE, CAppData>::iterator iAppData;
  2505. for (iAppData=m_AppData.begin(); iAppData != m_AppData.end(); iAppData++)
  2506. {
  2507. hr = InsertUpgradeEntry(iAppData->first, iAppData->second);
  2508. if (FAILED(hr))
  2509. {
  2510. return hr;
  2511. }
  2512. }
  2513. return hr;
  2514. }
  2515. //+--------------------------------------------------------------------------
  2516. //
  2517. // Member: CScopePane::InsertUpgradeEntry
  2518. //
  2519. // Synopsis: For every app that this app upgrades, place an entry in its
  2520. // upgrades set so that it points back to this one.
  2521. //
  2522. // Arguments: [cookie] -
  2523. // [data] -
  2524. //
  2525. // Returns:
  2526. //
  2527. // History: 2-02-1998 stevebl Created
  2528. //
  2529. // Notes: Needs to be able to deal with scripts that might not be in
  2530. // this OU.
  2531. //
  2532. //---------------------------------------------------------------------------
  2533. HRESULT CScopePane::InsertUpgradeEntry(MMC_COOKIE cookie, CAppData & data)
  2534. {
  2535. CString szCSPath;
  2536. HRESULT hr = GetClassStoreName(szCSPath, FALSE);
  2537. if (FAILED(hr))
  2538. {
  2539. DebugMsg((DM_WARNING, TEXT("GetClassStoreName failed with 0x%x"), hr));
  2540. }
  2541. UINT uUpgrades = data.m_pDetails->pInstallInfo->cUpgrades;
  2542. while (uUpgrades--)
  2543. {
  2544. map<CString, MMC_COOKIE>::iterator i = m_UpgradeIndex.find(GetUpgradeIndex(data.m_pDetails->pInstallInfo->prgUpgradeInfoList[uUpgrades].PackageGuid));
  2545. if (m_UpgradeIndex.end() != i)
  2546. {
  2547. // Make sure the entry isn't already added:
  2548. INSTALLINFO * pii = m_AppData[i->second].m_pDetails->pInstallInfo;
  2549. BOOL fExists = FALSE;
  2550. UINT uCount = pii->cUpgrades;
  2551. while (uCount--)
  2552. {
  2553. if (0 == memcmp(&data.m_pDetails->pInstallInfo->PackageGuid, &pii->prgUpgradeInfoList[uCount].PackageGuid, sizeof(GUID)))
  2554. {
  2555. // it already exists
  2556. fExists = TRUE;
  2557. break;
  2558. }
  2559. }
  2560. if (!fExists)
  2561. {
  2562. // Add the entry to this app.
  2563. // We don't need to update the class store because it should
  2564. // maintain referential integrity for us. But we do need to
  2565. // update our own internal structures so we're consistent with
  2566. // what's in the class store.
  2567. UINT n = ++(pii->cUpgrades);
  2568. UPGRADEINFO * prgUpgradeInfoList = (UPGRADEINFO *)OLEALLOC(sizeof(UPGRADEINFO) * n);
  2569. if (!prgUpgradeInfoList)
  2570. {
  2571. // out of memory
  2572. // back out the change (this would be unfortunate but not fatal)
  2573. pii->cUpgrades--;
  2574. }
  2575. else
  2576. {
  2577. if (n > 1)
  2578. {
  2579. memcpy(prgUpgradeInfoList, pii->prgUpgradeInfoList, sizeof(UPGRADEINFO) * (n-1));
  2580. OLESAFE_DELETE(pii->prgUpgradeInfoList);
  2581. }
  2582. OLESAFE_COPYSTRING(prgUpgradeInfoList[n-1].szClassStore, (LPOLESTR)((LPCWSTR)szCSPath));
  2583. memcpy(&prgUpgradeInfoList[n-1].PackageGuid, &data.m_pDetails->pInstallInfo->PackageGuid, sizeof(GUID));
  2584. prgUpgradeInfoList[n-1].Flag = UPGFLG_UpgradedBy;
  2585. pii->prgUpgradeInfoList = prgUpgradeInfoList;
  2586. }
  2587. }
  2588. }
  2589. }
  2590. return S_OK;
  2591. }
  2592. //+--------------------------------------------------------------------------
  2593. //
  2594. // Member: CScopePane::RemoveUpgradeEntry
  2595. //
  2596. // Synopsis: For every app that this app upgraded, remove the entry from
  2597. // its upgrades set.
  2598. //
  2599. // Arguments: [cookie] -
  2600. // [data] -
  2601. //
  2602. // Returns:
  2603. //
  2604. // History: 2-02-1998 stevebl Created
  2605. //
  2606. // Notes: Needs to be able to deal with scripts that might not be in
  2607. // this OU.
  2608. //
  2609. //---------------------------------------------------------------------------
  2610. HRESULT CScopePane::RemoveUpgradeEntry(MMC_COOKIE cookie, CAppData & data)
  2611. {
  2612. UINT uUpgradeIndex = data.m_pDetails->pInstallInfo->cUpgrades;
  2613. while (uUpgradeIndex--)
  2614. {
  2615. map<CString, MMC_COOKIE>::iterator i = m_UpgradeIndex.find(GetUpgradeIndex(data.m_pDetails->pInstallInfo->prgUpgradeInfoList[uUpgradeIndex].PackageGuid));
  2616. if (m_UpgradeIndex.end() != i)
  2617. {
  2618. // Find which entry needs to be erased.
  2619. INSTALLINFO * pii = m_AppData[i->second].m_pDetails->pInstallInfo;
  2620. UINT n = pii->cUpgrades;
  2621. while (n--)
  2622. {
  2623. if (0 == memcmp(&data.m_pDetails->pInstallInfo->PackageGuid, &pii->prgUpgradeInfoList[n].PackageGuid, sizeof(GUID)))
  2624. {
  2625. // Now free this entry, copy the last entry over this
  2626. // one and decrement cUpgrades. Don't need to actually
  2627. // reallocate the array because it will be freed later.
  2628. OLESAFE_DELETE(pii->prgUpgradeInfoList[n].szClassStore);
  2629. if (--(pii->cUpgrades))
  2630. {
  2631. memcpy(&pii->prgUpgradeInfoList[n], &pii->prgUpgradeInfoList[pii->cUpgrades], sizeof(UPGRADEINFO));
  2632. }
  2633. else
  2634. {
  2635. OLESAFE_DELETE(pii->prgUpgradeInfoList);
  2636. }
  2637. // If we ever were to need to update the class store,
  2638. // this is where we would do it.
  2639. break;
  2640. }
  2641. }
  2642. }
  2643. }
  2644. return S_OK;
  2645. }
  2646. //+--------------------------------------------------------------------------
  2647. //
  2648. // Member: CScopePane::PopulateExtensions
  2649. //
  2650. // Synopsis: Builds the file extension table from the list of applications.
  2651. //
  2652. // Arguments: (none)
  2653. //
  2654. // Returns:
  2655. //
  2656. // History: 1-29-1998 stevebl Created
  2657. //
  2658. //---------------------------------------------------------------------------
  2659. HRESULT CScopePane::PopulateExtensions()
  2660. {
  2661. HRESULT hr = S_OK;
  2662. // first erase the old extension list
  2663. m_Extensions.erase(m_Extensions.begin(), m_Extensions.end());
  2664. // now add each app's extensions to the table
  2665. map <MMC_COOKIE, CAppData>::iterator iAppData;
  2666. for (iAppData=m_AppData.begin(); iAppData != m_AppData.end(); iAppData++)
  2667. {
  2668. hr = InsertExtensionEntry(iAppData->first, iAppData->second);
  2669. if (FAILED(hr))
  2670. {
  2671. return hr;
  2672. }
  2673. }
  2674. if (m_pFileExt)
  2675. {
  2676. m_pFileExt->SendMessage(WM_USER_REFRESH, 0, 0);
  2677. }
  2678. return hr;
  2679. }
  2680. //+--------------------------------------------------------------------------
  2681. //
  2682. // Member: CScopePane::InsertExtensionEntry
  2683. //
  2684. // Synopsis: Adds a single entry to the extension tables.
  2685. //
  2686. // Arguments: [cookie] -
  2687. // [data] -
  2688. //
  2689. // Returns:
  2690. //
  2691. // History: 1-29-1998 stevebl Created
  2692. //
  2693. //---------------------------------------------------------------------------
  2694. HRESULT CScopePane::InsertExtensionEntry(MMC_COOKIE cookie, CAppData & data)
  2695. {
  2696. UINT n = data.m_pDetails->pActInfo->cShellFileExt;
  2697. while (n--)
  2698. {
  2699. m_Extensions[data.m_pDetails->pActInfo->prgShellFileExt[n]].insert(cookie);
  2700. }
  2701. return S_OK;
  2702. }
  2703. //+--------------------------------------------------------------------------
  2704. //
  2705. // Member: CScopePane::RemoveExtensionEntry
  2706. //
  2707. // Synopsis: Removes ane entry from the extension tables.
  2708. //
  2709. // Arguments: [cookie] -
  2710. // [data] -
  2711. //
  2712. // Returns:
  2713. //
  2714. // History: 1-29-1998 stevebl Created
  2715. //
  2716. //---------------------------------------------------------------------------
  2717. HRESULT CScopePane::RemoveExtensionEntry(MMC_COOKIE cookie, CAppData & data)
  2718. {
  2719. UINT n = data.m_pDetails->pActInfo->cShellFileExt;
  2720. while (n--)
  2721. {
  2722. m_Extensions[data.m_pDetails->pActInfo->prgShellFileExt[n]].erase(cookie);
  2723. if (m_Extensions[data.m_pDetails->pActInfo->prgShellFileExt[n]].empty())
  2724. {
  2725. m_Extensions.erase(data.m_pDetails->pActInfo->prgShellFileExt[n]);
  2726. }
  2727. }
  2728. return S_OK;
  2729. }
  2730. //+--------------------------------------------------------------------------
  2731. //
  2732. // Member: CScopePane::PrepareExtensions
  2733. //
  2734. // Synopsis: Sets extension priorities so that this data can be inserted
  2735. // into the extension list with the proper priority.
  2736. //
  2737. // Arguments: [pd] -
  2738. //
  2739. // Returns:
  2740. //
  2741. // Modifies:
  2742. //
  2743. // Derivation:
  2744. //
  2745. // History: 1-29-1998 stevebl Created
  2746. //
  2747. //---------------------------------------------------------------------------
  2748. HRESULT CScopePane::PrepareExtensions(PACKAGEDETAIL &pd)
  2749. {
  2750. UINT n = pd.pActInfo->cShellFileExt;
  2751. while (n--)
  2752. {
  2753. // For each extension that is going to be added, we need to assign
  2754. // it a priority that is one larger than the largest priority
  2755. // already added.
  2756. // NOTE: The odds of this number rolling over to 0 are so
  2757. // unlikely that it would be pointless to check for it. In any case
  2758. // the results of such a bug would be easy for the admin to remedy
  2759. // via the file extension priority dialog.
  2760. pd.pActInfo->prgPriority[n] = 0;
  2761. EXTLIST::iterator i;
  2762. CString sz = pd.pActInfo->prgShellFileExt[n];
  2763. for (i= m_Extensions[sz].begin(); i != m_Extensions[sz].end(); i++)
  2764. {
  2765. // look for the entry that matches this file extension
  2766. CAppData & data = m_AppData[*i];
  2767. UINT n2 = data.m_pDetails->pActInfo->cShellFileExt;
  2768. while (n2--)
  2769. {
  2770. if (0 == sz.CompareNoCase(data.m_pDetails->pActInfo->prgShellFileExt[n2]))
  2771. {
  2772. break;
  2773. }
  2774. }
  2775. if (data.m_pDetails->pActInfo->prgPriority[n2] >= pd.pActInfo->prgPriority[n])
  2776. {
  2777. pd.pActInfo->prgPriority[n] = data.m_pDetails->pActInfo->prgPriority[n2] + 1;
  2778. }
  2779. }
  2780. }
  2781. return S_OK;
  2782. }
  2783. //+--------------------------------------------------------------------------
  2784. //
  2785. // Member: CScopePane::ChangePackageState
  2786. //
  2787. // Synopsis: Changes the state of a package and puts up advisory message
  2788. // boxes informing the admin about the effects of the change.
  2789. //
  2790. // Arguments: [data] - entry to change
  2791. // [dwNewState] - new state
  2792. //
  2793. // History: 2-03-1998 stevebl Created
  2794. //
  2795. //---------------------------------------------------------------------------
  2796. STDMETHODIMP CScopePane::ChangePackageState(CAppData &data, DWORD dwNewState, BOOL fShowUI)
  2797. {
  2798. HRESULT hr = S_OK;
  2799. // first detect what's changed
  2800. DWORD dwOldState = data.m_pDetails->pInstallInfo->dwActFlags;
  2801. DWORD dwChange = dwOldState ^ dwNewState;
  2802. if (dwChange)
  2803. {
  2804. // commit changes
  2805. hr = m_pIClassAdmin->ChangePackageProperties(data.m_pDetails->pszPackageName, NULL, &dwNewState, NULL, NULL, NULL, NULL);
  2806. if (SUCCEEDED(hr))
  2807. {
  2808. if (data.m_fVisible)
  2809. {
  2810. data.m_pDetails->pInstallInfo->dwActFlags = dwNewState;
  2811. RESULTDATAITEM rd;
  2812. memset(&rd, 0, sizeof(rd));
  2813. rd.mask = RDI_IMAGE;
  2814. rd.itemID = data.m_itemID;
  2815. rd.nImage = data.GetImageIndex(this);
  2816. set <CResultPane *>::iterator i;
  2817. for (i = m_sResultPane.begin(); i != m_sResultPane.end(); i++)
  2818. {
  2819. (*i)->m_pResult->SetItem(&rd);
  2820. (*i)->m_pResult->Sort((*i)->m_nSortColumn, (*i)->m_dwSortOptions, -1);
  2821. }
  2822. }
  2823. data.NotifyChange();
  2824. if (FAILED(m_pIGPEInformation->PolicyChanged(m_fMachine, TRUE, &guidExtension,
  2825. m_fMachine ? &guidMachSnapin
  2826. : &guidUserSnapin)))
  2827. {
  2828. ReportPolicyChangedError(m_hwndMainWindow);
  2829. }
  2830. }
  2831. else
  2832. {
  2833. DebugMsg((DM_WARNING, TEXT("ChangePackageProperties failed with 0x%x"), hr));
  2834. }
  2835. }
  2836. return hr;
  2837. }
  2838. HRESULT CScopePane::ClearCategories()
  2839. {
  2840. while (m_CatList.cCategory)
  2841. {
  2842. m_CatList.cCategory--;
  2843. OLESAFE_DELETE(m_CatList.pCategoryInfo[m_CatList.cCategory].pszDescription);
  2844. }
  2845. OLESAFE_DELETE(m_CatList.pCategoryInfo);
  2846. return S_OK;
  2847. }
  2848. //+--------------------------------------------------------------------------
  2849. //
  2850. // Function: GetUpgradeIndex
  2851. //
  2852. // Synopsis: utility function that returns an upgrade index entry for a package.
  2853. //
  2854. // Arguments: [PackageID] - the PackageID guid
  2855. //
  2856. // Returns: S_OK on success
  2857. //
  2858. // History: 8-12-1998 stevebl Created
  2859. //
  2860. // Notes: Pretty simple really, the index is just the string form of
  2861. // the GUID.
  2862. //
  2863. //---------------------------------------------------------------------------
  2864. CString GetUpgradeIndex(GUID & PackageID)
  2865. {
  2866. CString szIndex;
  2867. WCHAR wsz[256];
  2868. StringFromGUID2(PackageID, wsz, 256);
  2869. return wsz;
  2870. }
  2871. //+--------------------------------------------------------------------------
  2872. //
  2873. // Member: CScopePane::GetPackageNameFromUpgradeInfo
  2874. //
  2875. // Synopsis: returns the name of a package given its PackageGuid and CSPath
  2876. //
  2877. // Arguments: [szPackageName] - [out] name of the package associated with
  2878. // this script
  2879. // [szScript] - [in] path to the script
  2880. //
  2881. // Returns: S_OK - found a package associated with this script
  2882. // (other) - failed to find a package (could be for any number
  2883. // of reasons)
  2884. //
  2885. // History: 4-07-1998 stevebl Created
  2886. //
  2887. // Notes: In cases where the package does not reside in this
  2888. // container, the package name will be returned as
  2889. // "Package Name (container name)"
  2890. // Note that this does not return the friendly name of the
  2891. // MSI package, it returns the name of the package entry in the
  2892. // class store. The two are not always the same.
  2893. //
  2894. //---------------------------------------------------------------------------
  2895. HRESULT CScopePane::GetPackageNameFromUpgradeInfo(CString & szPackageName, GUID &PackageGuid, LPOLESTR szCSPath)
  2896. {
  2897. HRESULT hr;
  2898. IEnumPackage * pIPE = NULL;
  2899. CString szMyCSPath;
  2900. hr = GetClassStoreName(szMyCSPath, FALSE);
  2901. if (FAILED(hr))
  2902. {
  2903. DebugMsg((DM_WARNING, TEXT("GetClassStoreName failed with 0x%x"), hr));
  2904. }
  2905. // see if it's in our container
  2906. if (0 == _wcsicmp((LPOLESTR)((LPCWSTR)szMyCSPath), szCSPath))
  2907. {
  2908. hr = E_FAIL;
  2909. map <CString, MMC_COOKIE>::iterator i = m_UpgradeIndex.find(GetUpgradeIndex(PackageGuid));
  2910. if (m_UpgradeIndex.end() != i)
  2911. {
  2912. szPackageName = m_AppData[i->second].m_pDetails->pszPackageName;
  2913. hr = S_OK;
  2914. }
  2915. }
  2916. else
  2917. {
  2918. IClassAdmin * pIClassAdmin;
  2919. hr = CsGetClassStore((LPOLESTR)((LPCOLESTR)szCSPath), (LPVOID*)&pIClassAdmin);
  2920. if (SUCCEEDED(hr))
  2921. {
  2922. PACKAGEDETAIL pd;
  2923. hr = pIClassAdmin->GetPackageDetailsFromGuid(PackageGuid,
  2924. &pd);
  2925. if (SUCCEEDED(hr))
  2926. {
  2927. if (0 == (pd.pInstallInfo->dwActFlags & (ACTFLG_Orphan | ACTFLG_Uninstall)))
  2928. {
  2929. GUID guid;
  2930. LPOLESTR pszPolicyName;
  2931. hr = pIClassAdmin->GetGPOInfo(&guid,
  2932. &pszPolicyName);
  2933. if (SUCCEEDED(hr))
  2934. {
  2935. szPackageName = pd.pszPackageName;
  2936. szPackageName += L" (";
  2937. szPackageName += pszPolicyName;
  2938. szPackageName += L")";
  2939. OLESAFE_DELETE(pszPolicyName);
  2940. }
  2941. }
  2942. else
  2943. {
  2944. // this app is marked as deleted
  2945. hr = E_FAIL;
  2946. }
  2947. ReleasePackageDetail(&pd);
  2948. }
  2949. pIClassAdmin->Release();
  2950. }
  2951. }
  2952. return hr;
  2953. }
  2954. //+--------------------------------------------------------------------------
  2955. //
  2956. // Function: GetMsiProperty
  2957. //
  2958. // Synopsis: Retrieves a property from the Property table of an MSI package.
  2959. //
  2960. // Arguments: [szPackagePath] - path to the MSI package
  2961. // [szProperty] - property to fetch
  2962. // [szValue] - buffer to contain the value
  2963. // [puiSize] - size of the buffer
  2964. //
  2965. // Returns: ERROR_SUCCESS if successful
  2966. //
  2967. // History: 3-25-1998 stevebl Created
  2968. //
  2969. //---------------------------------------------------------------------------
  2970. UINT GetMsiProperty(const TCHAR * szPackagePath, const TCHAR* szProperty, TCHAR* szValue, DWORD* puiSize)
  2971. {
  2972. MSIHANDLE hDatabase;
  2973. UINT msiReturn = MsiOpenDatabase(szPackagePath, MSIDBOPEN_READONLY, &hDatabase);
  2974. if (ERROR_SUCCESS == msiReturn)
  2975. {
  2976. CString szQuery;
  2977. szQuery.Format(L"SELECT `Value` FROM `Property` WHERE `Property`='%s'", szProperty);
  2978. MSIHANDLE hView;
  2979. msiReturn = MsiDatabaseOpenView(hDatabase, szQuery, &hView);
  2980. if (ERROR_SUCCESS == msiReturn)
  2981. {
  2982. msiReturn = MsiViewExecute(hView, 0);
  2983. if (ERROR_SUCCESS == msiReturn)
  2984. {
  2985. MSIHANDLE hRecord;
  2986. msiReturn = MsiViewFetch(hView, &hRecord);
  2987. if (ERROR_SUCCESS == msiReturn)
  2988. {
  2989. msiReturn = MsiRecordGetString(hRecord, 1, szValue, puiSize);
  2990. MsiCloseHandle(hRecord);
  2991. }
  2992. }
  2993. MsiCloseHandle(hView);
  2994. }
  2995. MsiCloseHandle(hDatabase);
  2996. }
  2997. return msiReturn;
  2998. }
  2999. //+--------------------------------------------------------------------------
  3000. //
  3001. // Function: GetCapitalizedExt
  3002. //
  3003. // Synopsis: Given a file name, this function finds the filename
  3004. // extension, and returns it capitalized.
  3005. //
  3006. // Arguments:
  3007. // [in] [szName] The file name
  3008. // [out][szExt] The capitalized extension
  3009. //
  3010. // Returns:
  3011. // TRUE - an extension was found
  3012. // FALSE - an extension could not be found
  3013. //
  3014. // History: 5/20/1998 RahulTh created
  3015. //
  3016. // Notes: If an extension cannot be found, then this function makes
  3017. // szExt an empty string
  3018. //
  3019. //---------------------------------------------------------------------------
  3020. BOOL GetCapitalizedExt (LPCOLESTR szName, CString& szExt)
  3021. {
  3022. int slashpos, dotpos;
  3023. BOOL fRetVal = FALSE;
  3024. CString szFileName = szName;
  3025. szExt.Empty(); //to be on the safe side
  3026. //get the positions of the last . and last backslash
  3027. dotpos = szFileName.ReverseFind('.');
  3028. slashpos = szFileName.ReverseFind('\\');
  3029. //if the last dot occurs after the last slash, this file has an extension
  3030. if (dotpos > slashpos)
  3031. {
  3032. szExt = szFileName.Mid(dotpos + 1);
  3033. szExt.MakeUpper();
  3034. fRetVal = TRUE;
  3035. }
  3036. return fRetVal;
  3037. }