Source code of Windows XP (NT5)
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.

601 lines
19 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1994 - 1998.
  5. //
  6. // File: deploy.cpp
  7. //
  8. // Contents: application deployment property page
  9. //
  10. // Classes: CDeploy
  11. //
  12. // History: 03-14-1998 stevebl Commented
  13. //
  14. //---------------------------------------------------------------------------
  15. #include "precomp.hxx"
  16. #ifdef _DEBUG
  17. #define new DEBUG_NEW
  18. #undef THIS_FILE
  19. static char THIS_FILE[] = __FILE__;
  20. #endif
  21. //
  22. // Guid of appmgmt client side GP extension, and guids for snapins
  23. //
  24. GUID guidExtension = { 0xc6dc5466, 0x785a, 0x11d2, {0x84, 0xd0, 0x00, 0xc0, 0x4f, 0xb1, 0x69, 0xf7}};
  25. GUID guidUserSnapin = CLSID_Snapin;
  26. GUID guidMachSnapin = CLSID_MachineSnapin;
  27. GUID guidRSOPUserSnapin = CLSID_RSOP_Snapin;
  28. GUID guidRSOPMachSnapin = CLSID_RSOP_MachineSnapin;
  29. /////////////////////////////////////////////////////////////////////////////
  30. // CDeploy property page
  31. IMPLEMENT_DYNCREATE(CDeploy, CPropertyPage)
  32. CDeploy::CDeploy() : CPropertyPage(CDeploy::IDD)
  33. {
  34. //{{AFX_DATA_INIT(CDeploy)
  35. m_fAutoInst = FALSE;
  36. m_fFullInst = FALSE;
  37. m_iUI = -1;
  38. m_iDeployment = -1;
  39. m_fUninstallOnPolicyRemoval = FALSE;
  40. m_hConsoleHandle = NULL;
  41. m_fNotUserInstall = FALSE;
  42. //}}AFX_DATA_INIT
  43. m_pIClassAdmin = NULL;
  44. m_fPreDeploy = FALSE;
  45. m_ppThis = NULL;
  46. m_dlgAdvDep.m_pDeploy = this;
  47. }
  48. CDeploy::~CDeploy()
  49. {
  50. if (m_ppThis)
  51. {
  52. *m_ppThis = NULL;
  53. }
  54. MMCFreeNotifyHandle(m_hConsoleHandle);
  55. if (m_pIClassAdmin)
  56. {
  57. m_pIClassAdmin->Release();
  58. }
  59. }
  60. void CDeploy::DoDataExchange(CDataExchange* pDX)
  61. {
  62. CPropertyPage::DoDataExchange(pDX);
  63. //{{AFX_DATA_MAP(CDeploy)
  64. DDX_Check(pDX, IDC_CHECK2, m_fAutoInst);
  65. DDX_Radio(pDX, IDC_RADIO3, m_iUI);
  66. DDX_Radio(pDX, IDC_RADIO2, m_iDeployment);
  67. DDX_Check(pDX, IDC_CHECK1, m_fUninstallOnPolicyRemoval);
  68. DDX_Check(pDX, IDC_CHECK3, m_fNotUserInstall);
  69. DDX_Check(pDX, IDC_CHECK4, m_fFullInst);
  70. //}}AFX_DATA_MAP
  71. }
  72. BEGIN_MESSAGE_MAP(CDeploy, CPropertyPage)
  73. //{{AFX_MSG_MAP(CDeploy)
  74. ON_BN_CLICKED(IDC_BUTTON1, OnAdvanced)
  75. ON_BN_CLICKED(IDC_RADIO2, OnPublished)
  76. ON_BN_CLICKED(IDC_RADIO1, OnAssigned)
  77. ON_BN_CLICKED(IDC_CHECK2, OnChanged)
  78. ON_BN_CLICKED(IDC_CHECK3, OnChanged)
  79. ON_BN_CLICKED(IDC_RADIO3, OnChanged)
  80. ON_BN_CLICKED(IDC_RADIO4, OnChanged)
  81. ON_BN_CLICKED(IDC_CHECK1, OnChanged)
  82. ON_BN_CLICKED(IDC_CHECK4, OnChanged)
  83. ON_WM_DESTROY()
  84. ON_WM_CONTEXTMENU()
  85. //}}AFX_MSG_MAP
  86. END_MESSAGE_MAP()
  87. /////////////////////////////////////////////////////////////////////////////
  88. // CDeploy message handlers
  89. BOOL CDeploy::OnApply()
  90. {
  91. if (m_fRSOP)
  92. {
  93. return CPropertyPage::OnApply();
  94. }
  95. DWORD dwActFlags = m_pData->m_pDetails->pInstallInfo->dwActFlags;
  96. dwActFlags &= ~(ACTFLG_Assigned | ACTFLG_Published |
  97. ACTFLG_OnDemandInstall | ACTFLG_UserInstall |
  98. ACTFLG_OrphanOnPolicyRemoval | ACTFLG_UninstallOnPolicyRemoval |
  99. ACTFLG_InstallUserAssign |
  100. ACTFLG_ExcludeX86OnIA64 | ACTFLG_IgnoreLanguage | ACTFLG_UninstallUnmanaged);
  101. switch (m_iDeployment)
  102. {
  103. case 2:
  104. // Disabled
  105. break;
  106. case 0:
  107. // Published
  108. dwActFlags |= ACTFLG_Published;
  109. if (m_fAutoInst)
  110. {
  111. dwActFlags |= ACTFLG_OnDemandInstall;
  112. }
  113. if (!m_fNotUserInstall)
  114. {
  115. dwActFlags |= ACTFLG_UserInstall;
  116. }
  117. break;
  118. case 1:
  119. // Assigned
  120. dwActFlags |= (ACTFLG_Assigned | ACTFLG_OnDemandInstall);
  121. if (!m_fNotUserInstall)
  122. {
  123. dwActFlags |= ACTFLG_UserInstall;
  124. }
  125. if (m_fFullInst)
  126. {
  127. dwActFlags |= ACTFLG_InstallUserAssign;
  128. }
  129. break;
  130. default:
  131. break;
  132. }
  133. if (m_pData->m_pDetails->pInstallInfo->PathType == SetupNamePath)
  134. {
  135. // legacy app
  136. if (m_dlgAdvDep.m_f32On64)
  137. dwActFlags |= ACTFLG_ExcludeX86OnIA64;
  138. }
  139. else
  140. {
  141. // not a legacy app
  142. if (!m_dlgAdvDep.m_f32On64)
  143. dwActFlags |= ACTFLG_ExcludeX86OnIA64;
  144. }
  145. if (m_fUninstallOnPolicyRemoval)
  146. {
  147. dwActFlags |= ACTFLG_UninstallOnPolicyRemoval;
  148. }
  149. else
  150. {
  151. // never set this flag for legacy applications
  152. if (m_pData->m_pDetails->pInstallInfo->PathType != SetupNamePath)
  153. dwActFlags |= ACTFLG_OrphanOnPolicyRemoval;
  154. }
  155. if (m_dlgAdvDep.m_fIgnoreLCID)
  156. {
  157. dwActFlags |= ACTFLG_IgnoreLanguage;
  158. }
  159. if (m_dlgAdvDep.m_fUninstallUnmanaged)
  160. {
  161. dwActFlags |= ACTFLG_UninstallUnmanaged;
  162. }
  163. UINT UILevel;
  164. switch (m_iUI)
  165. {
  166. case 1:
  167. UILevel = INSTALLUILEVEL_FULL;
  168. break;
  169. case 0:
  170. default:
  171. UILevel = INSTALLUILEVEL_BASIC;
  172. break;
  173. }
  174. HRESULT hr = E_FAIL;
  175. if (m_pIClassAdmin)
  176. {
  177. hr = m_pIClassAdmin->ChangePackageProperties(m_pData->m_pDetails->pszPackageName,
  178. NULL,
  179. &dwActFlags,
  180. NULL,
  181. NULL,
  182. &UILevel,
  183. NULL);
  184. }
  185. if (SUCCEEDED(hr))
  186. {
  187. m_pData->m_pDetails->pInstallInfo->InstallUiLevel = UILevel;
  188. m_pData->m_pDetails->pInstallInfo->dwActFlags = dwActFlags;
  189. #if 0
  190. if (FAILED(m_pIGPEInformation->PolicyChanged(m_fMachine,
  191. TRUE,
  192. &guidExtension,
  193. m_fMachine ? &guidMachSnapin
  194. : &guidUserSnapin)))
  195. {
  196. ReportPolicyChangedError(m_hWnd);
  197. }
  198. #endif
  199. if (!m_fPreDeploy)
  200. {
  201. MMCPropertyChangeNotify(m_hConsoleHandle, (long) m_cookie);
  202. }
  203. else
  204. {
  205. // we're in pre-deploy mode - check to see if the fExtensionsOnly
  206. // flag has changed (which requires a re-deploy)
  207. // note that these two flags are normally the same,
  208. // meaning that when they're different, the user has requested a
  209. // change.
  210. if (m_dlgAdvDep.m_fIncludeOLEInfo != m_pData->m_pDetails->pActInfo->bHasClasses)
  211. {
  212. // need to redeploy
  213. BOOL fBuildSucceeded = FALSE;
  214. PACKAGEDETAIL * ppd;
  215. //
  216. // Apply the current setting for classes
  217. //
  218. m_pData->m_pDetails->pActInfo->bHasClasses = m_dlgAdvDep.m_fIncludeOLEInfo;
  219. if (FAILED(CopyPackageDetail(ppd, m_pData->m_pDetails)))
  220. {
  221. return FALSE;
  222. }
  223. CString sz;
  224. // Create a name for the new script file.
  225. // set the script path
  226. GUID guid;
  227. HRESULT hr = CoCreateGuid(&guid);
  228. if (FAILED(hr))
  229. {
  230. // undone
  231. }
  232. //
  233. // For MSI packages, we must regenerate class information
  234. //
  235. if ( DrwFilePath == ppd->pInstallInfo->PathType )
  236. {
  237. OLECHAR szGuid [256];
  238. StringFromGUID2(guid, szGuid, 256);
  239. CString szScriptFile = m_pScopePane->m_szGPT_Path;
  240. szScriptFile += L"\\";
  241. szScriptFile += szGuid;
  242. szScriptFile += L".aas";
  243. OLESAFE_DELETE(ppd->pInstallInfo->pszScriptPath);
  244. OLESAFE_COPYSTRING(ppd->pInstallInfo->pszScriptPath, szScriptFile);
  245. CString szOldName = ppd->pszPackageName;
  246. hr = BuildScriptAndGetActInfo(*ppd, !m_dlgAdvDep.m_fIncludeOLEInfo);
  247. if ( SUCCEEDED( hr ) )
  248. {
  249. if (0 != wcscmp(m_szInitialPackageName, szOldName))
  250. {
  251. // The User changed the name so we have to preserve his choice.
  252. // If the user hasn't changed the package name then it's ok to
  253. // set the packagename to whatever is in the script file.
  254. OLESAFE_DELETE(ppd->pszPackageName);
  255. OLESAFE_COPYSTRING(ppd->pszPackageName, szOldName);
  256. }
  257. }
  258. }
  259. if (SUCCEEDED(hr))
  260. {
  261. fBuildSucceeded = TRUE;
  262. hr = m_pScopePane->PrepareExtensions(*ppd);
  263. if (SUCCEEDED(hr))
  264. {
  265. CString szUniqueName;
  266. int nHint;
  267. nHint = 1;
  268. m_pScopePane->GetUniquePackageName(ppd->pszPackageName, szUniqueName, nHint);
  269. OLESAFE_DELETE(ppd->pszPackageName);
  270. OLESAFE_COPYSTRING(ppd->pszPackageName, szUniqueName);
  271. if ( ppd->pszPackageName )
  272. {
  273. hr = m_pIClassAdmin->RedeployPackage(
  274. &m_pData->m_pDetails->pInstallInfo->PackageGuid,
  275. ppd);
  276. }
  277. else
  278. {
  279. hr = E_OUTOFMEMORY;
  280. }
  281. if (SUCCEEDED(hr))
  282. {
  283. // delete the old script
  284. DeleteFile(m_pData->m_pDetails->pInstallInfo->pszScriptPath);
  285. // update indexes and property sheets
  286. m_pScopePane->RemoveExtensionEntry(m_cookie, *m_pData);
  287. m_pScopePane->RemoveUpgradeEntry(m_cookie, *m_pData);
  288. FreePackageDetail(m_pData->m_pDetails);
  289. m_pData->m_pDetails = ppd;
  290. m_pScopePane->InsertExtensionEntry(m_cookie, *m_pData);
  291. m_pScopePane->InsertUpgradeEntry(m_cookie, *m_pData);
  292. if (m_pScopePane->m_pFileExt)
  293. {
  294. m_pScopePane->m_pFileExt->SendMessage(WM_USER_REFRESH, 0, 0);
  295. }
  296. }
  297. }
  298. }
  299. if (FAILED(hr))
  300. {
  301. CString sz;
  302. sz.LoadString(fBuildSucceeded ? IDS_REDEPLOY_FAILED_IN_CS : IDS_REDEPLOY_FAILED);
  303. ReportGeneralPropertySheetError(m_hWnd, sz, hr);
  304. // delete new script file (assuming it was created)
  305. if ( ( DrwFilePath == ppd->pInstallInfo->PathType ) &&
  306. ppd->pInstallInfo->pszScriptPath )
  307. {
  308. DeleteFile(ppd->pInstallInfo->pszScriptPath);
  309. }
  310. FreePackageDetail(ppd);
  311. return FALSE;
  312. }
  313. }
  314. }
  315. }
  316. else
  317. {
  318. DebugMsg((DM_WARNING, TEXT("ChangePackageProperties failed with 0x%x"), hr));
  319. CString sz;
  320. sz.LoadString(IDS_CHANGEFAILED);
  321. ReportGeneralPropertySheetError(m_hWnd, sz, hr);
  322. return FALSE;
  323. }
  324. return CPropertyPage::OnApply();
  325. }
  326. BOOL CDeploy::OnInitDialog()
  327. {
  328. RefreshData();
  329. if (m_pData->m_pDetails->pInstallInfo->PathType == SetupNamePath)
  330. {
  331. // legacy apps can't be assigned
  332. GetDlgItem(IDC_RADIO1)->EnableWindow(FALSE);
  333. // legacy apps don't have a UI level
  334. GetDlgItem(IDC_RADIO3)->EnableWindow(FALSE);
  335. GetDlgItem(IDC_RADIO4)->EnableWindow(FALSE);
  336. // legacy apps can't be uninstalled
  337. GetDlgItem(IDC_CHECK1)->EnableWindow(FALSE);
  338. }
  339. m_szInitialPackageName = m_pData->m_pDetails->pszPackageName;
  340. if (m_fMachine)
  341. {
  342. GetDlgItem(IDC_RADIO2)->EnableWindow(FALSE);
  343. // machine deployed apps don't have a UI
  344. GetDlgItem(IDC_RADIO3)->EnableWindow(FALSE);
  345. GetDlgItem(IDC_RADIO4)->EnableWindow(FALSE);
  346. }
  347. if (0 != (m_pData->m_pDetails->pInstallInfo->dwActFlags & ACTFLG_MinimalInstallUI))
  348. {
  349. GetDlgItem(IDC_RADIO4)->EnableWindow(FALSE);
  350. }
  351. CPropertyPage::OnInitDialog();
  352. return TRUE; // return TRUE unless you set the focus to a control
  353. // EXCEPTION: OCX Property Pages should return FALSE
  354. }
  355. void CDeploy::OnAdvanced()
  356. {
  357. BOOL fIgnoreLCID = m_dlgAdvDep.m_fIgnoreLCID;
  358. BOOL fInstallOnAlpha = m_dlgAdvDep.m_fInstallOnAlpha;
  359. BOOL fUninstallUnmanaged = m_dlgAdvDep.m_fUninstallUnmanaged;
  360. BOOL f32On64 = m_dlgAdvDep.m_f32On64;
  361. BOOL fIncludeOLEInfo = m_dlgAdvDep.m_fIncludeOLEInfo;
  362. m_dlgAdvDep.m_szScriptName = m_pData->m_pDetails->pInstallInfo->pszScriptPath;
  363. if (IDOK == m_dlgAdvDep.DoModal())
  364. {
  365. if (fIgnoreLCID != m_dlgAdvDep.m_fIgnoreLCID
  366. || fInstallOnAlpha != m_dlgAdvDep.m_fInstallOnAlpha
  367. || fUninstallUnmanaged != m_dlgAdvDep.m_fUninstallUnmanaged
  368. || f32On64 != m_dlgAdvDep.m_f32On64
  369. || fIncludeOLEInfo != m_dlgAdvDep.m_fIncludeOLEInfo)
  370. {
  371. if (!m_fPreDeploy)
  372. SetModified();
  373. }
  374. }
  375. }
  376. void CDeploy::OnDisable()
  377. {
  378. if (!m_fPreDeploy)
  379. SetModified();
  380. m_fAutoInst = FALSE;
  381. GetDlgItem(IDC_CHECK2)->EnableWindow(FALSE);
  382. GetDlgItem(IDC_CHECK3)->EnableWindow(FALSE);
  383. if (NULL == GetFocus())
  384. {
  385. GetParent()->GetDlgItem(IDOK)->SetFocus();
  386. }
  387. }
  388. void CDeploy::OnPublished()
  389. {
  390. if (!m_fPreDeploy)
  391. SetModified();
  392. GetDlgItem(IDC_CHECK2)->EnableWindow(TRUE);
  393. GetDlgItem(IDC_CHECK3)->EnableWindow(!m_fMachine);
  394. GetDlgItem(IDC_CHECK4)->EnableWindow(FALSE);
  395. if (NULL == GetFocus())
  396. {
  397. GetParent()->GetDlgItem(IDOK)->SetFocus();
  398. }
  399. }
  400. void CDeploy::OnAssigned()
  401. {
  402. if (!m_fPreDeploy)
  403. SetModified();
  404. m_fAutoInst = TRUE;
  405. GetDlgItem(IDC_CHECK2)->EnableWindow(FALSE);
  406. GetDlgItem(IDC_CHECK3)->EnableWindow(!m_fMachine);
  407. GetDlgItem(IDC_CHECK4)->EnableWindow(TRUE);
  408. if (NULL == GetFocus())
  409. {
  410. GetParent()->GetDlgItem(IDOK)->SetFocus();
  411. }
  412. }
  413. void CDeploy::OnChanged()
  414. {
  415. if (!m_fPreDeploy)
  416. SetModified();
  417. }
  418. LRESULT CDeploy::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
  419. {
  420. switch (message)
  421. {
  422. case WM_HELP:
  423. StandardHelp((HWND)((LPHELPINFO) lParam)->hItemHandle, IDD);
  424. return 0;
  425. case WM_USER_REFRESH:
  426. RefreshData();
  427. UpdateData(FALSE);
  428. return 0;
  429. case WM_USER_CLOSE:
  430. m_dlgAdvDep.EndDialog(IDCANCEL);
  431. return GetOwner()->SendMessage(WM_CLOSE);
  432. default:
  433. return CPropertyPage::WindowProc(message, wParam, lParam);
  434. }
  435. }
  436. void CDeploy::RefreshData(void)
  437. {
  438. DWORD dwActFlags = m_pData->m_pDetails->pInstallInfo->dwActFlags;
  439. m_fAutoInst = (0 != (dwActFlags & ACTFLG_OnDemandInstall));
  440. m_fNotUserInstall = (0 == (dwActFlags & ACTFLG_UserInstall));
  441. m_fFullInst = (0 != (dwActFlags & ACTFLG_InstallUserAssign));
  442. if (dwActFlags & ACTFLG_Assigned)
  443. {
  444. m_iDeployment = 1;
  445. GetDlgItem(IDC_CHECK2)->EnableWindow(FALSE);
  446. GetDlgItem(IDC_CHECK3)->EnableWindow(!m_fMachine);
  447. // Only enable full assign checkbox when an app is
  448. // assigned and not legacy. And only enable this
  449. // when we're in USER mode.
  450. // Of course .ZAP (legacy) packages can't be assigned
  451. // anyway so we don't actually need to check for that.
  452. GetDlgItem(IDC_CHECK4)->EnableWindow( m_fMachine == FALSE);
  453. }
  454. else if (dwActFlags & ACTFLG_Published)
  455. {
  456. m_iDeployment = 0;
  457. GetDlgItem(IDC_CHECK2)->EnableWindow(TRUE);
  458. GetDlgItem(IDC_CHECK3)->EnableWindow(!m_fMachine);
  459. GetDlgItem(IDC_CHECK4)->EnableWindow(FALSE);
  460. }
  461. else
  462. {
  463. m_iDeployment = 2;
  464. GetDlgItem(IDC_CHECK2)->EnableWindow(FALSE);
  465. GetDlgItem(IDC_CHECK3)->EnableWindow(FALSE);
  466. GetDlgItem(IDC_CHECK4)->EnableWindow(FALSE);
  467. }
  468. if (this->m_fRSOP)
  469. {
  470. // disable EVERYTHING
  471. GetDlgItem(IDC_RADIO1)->EnableWindow(FALSE);
  472. GetDlgItem(IDC_RADIO2)->EnableWindow(FALSE);
  473. GetDlgItem(IDC_RADIO3)->EnableWindow(FALSE);
  474. GetDlgItem(IDC_RADIO4)->EnableWindow(FALSE);
  475. GetDlgItem(IDC_CHECK1)->EnableWindow(FALSE);
  476. GetDlgItem(IDC_CHECK2)->EnableWindow(FALSE);
  477. GetDlgItem(IDC_CHECK3)->EnableWindow(FALSE);
  478. GetDlgItem(IDC_CHECK4)->EnableWindow(FALSE);
  479. }
  480. if (NULL == GetFocus())
  481. {
  482. GetParent()->GetDlgItem(IDOK)->SetFocus();
  483. }
  484. if (dwActFlags & ACTFLG_UninstallOnPolicyRemoval)
  485. {
  486. m_fUninstallOnPolicyRemoval = TRUE;
  487. }
  488. else
  489. {
  490. m_fUninstallOnPolicyRemoval = FALSE;
  491. }
  492. // initialize the state flags for the advanced dialog
  493. m_dlgAdvDep.m_szDeploymentCount.Format(TEXT("%u"), m_pData->m_pDetails->pInstallInfo->dwRevision);
  494. OLECHAR szTemp[80];
  495. StringFromGUID2(m_pData->m_pDetails->pInstallInfo->ProductCode,
  496. szTemp,
  497. sizeof(szTemp) / sizeof(szTemp[0]));
  498. m_dlgAdvDep.m_szProductCode = szTemp;
  499. m_dlgAdvDep.m_f32On64 = ((dwActFlags & ACTFLG_ExcludeX86OnIA64) == ACTFLG_ExcludeX86OnIA64);
  500. if (m_pData->m_pDetails->pInstallInfo->PathType != SetupNamePath)
  501. {
  502. // this is not a legacy app
  503. // reverse the sense of m_f32On64
  504. m_dlgAdvDep.m_f32On64 = !m_dlgAdvDep.m_f32On64;
  505. }
  506. if (dwActFlags & ACTFLG_UninstallUnmanaged)
  507. {
  508. m_dlgAdvDep.m_fUninstallUnmanaged = TRUE;
  509. }
  510. else
  511. {
  512. m_dlgAdvDep.m_fUninstallUnmanaged = FALSE;
  513. }
  514. m_dlgAdvDep.m_fInstallOnAlpha = FALSE;
  515. m_dlgAdvDep.m_fIncludeOLEInfo = m_pData->m_pDetails->pActInfo->bHasClasses;
  516. if (dwActFlags & ACTFLG_IgnoreLanguage)
  517. {
  518. m_dlgAdvDep.m_fIgnoreLCID = TRUE;
  519. }
  520. else
  521. {
  522. m_dlgAdvDep.m_fIgnoreLCID = FALSE;
  523. }
  524. switch (m_pData->m_pDetails->pInstallInfo->InstallUiLevel)
  525. {
  526. case INSTALLUILEVEL_FULL:
  527. m_iUI = 1;
  528. break;
  529. case INSTALLUILEVEL_BASIC:
  530. default:
  531. m_iUI = 0;
  532. break;
  533. }
  534. SetModified(FALSE);
  535. }
  536. void CDeploy::OnContextMenu(CWnd* pWnd, CPoint point)
  537. {
  538. StandardContextMenu(pWnd->m_hWnd, IDD_DEPLOYMENT);
  539. }