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.

1297 lines
29 KiB

  1. /*++
  2. Copyright (c) 1994-2000 Microsoft Corporation
  3. Module Name :
  4. metaback.cpp
  5. Abstract:
  6. Metabase backup and restore dialog
  7. Author:
  8. Ronald Meijer (ronaldm)
  9. Sergei Antonov (sergeia)
  10. Project:
  11. Internet Services Manager
  12. Revision History:
  13. --*/
  14. //
  15. // Include Files
  16. //
  17. #include "stdafx.h"
  18. #include "common.h"
  19. #include "InetMgrApp.h"
  20. #include "iisobj.h"
  21. #include "mddefw.h"
  22. #include "metaback.h"
  23. #include "aclpage.h"
  24. #include "savedata.h"
  25. #include "remoteenv.h"
  26. #include "svc.h"
  27. #include "shutdown.h"
  28. #ifdef _DEBUG
  29. #define new DEBUG_NEW
  30. #undef THIS_FILE
  31. static char THIS_FILE[] = __FILE__;
  32. #endif
  33. //
  34. // CBackupsListBox : a listbox of CBackup objects
  35. //
  36. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  37. //
  38. // Column width relative weights
  39. //
  40. #define WT_LOCATION 8
  41. #define WT_VERSION 2
  42. #define WT_DATE 6
  43. //
  44. // Registry key name for this dialog
  45. //
  46. const TCHAR g_szRegKey[] = _T("MetaBack");
  47. const TCHAR g_szIISAdminService[] = _T("IISADMIN");
  48. IMPLEMENT_DYNAMIC(CBackupsListBox, CHeaderListBox);
  49. const int CBackupsListBox::nBitmaps = 1;
  50. #define HAS_BACKUP_PASSWORD(x) \
  51. ((x)->QueryMajorVersion() == 5 && (x)->QueryMinorVersion() == 1) || ((x)->QueryMajorVersion() >= 6)
  52. #define HAS_BACKUP_HISTORY(x) \
  53. ((x)->QueryMajorVersion() >= 6)
  54. CBackupsListBox::CBackupsListBox()
  55. /*++
  56. Routine Description:
  57. Backups listbox constructor
  58. Arguments:
  59. None
  60. Return Value:
  61. N/A
  62. --*/
  63. : CHeaderListBox(HLS_STRETCH, g_szRegKey)
  64. {
  65. }
  66. void
  67. CBackupsListBox::DrawItemEx(
  68. IN CRMCListBoxDrawStruct & ds
  69. )
  70. /*++
  71. Routine Description:
  72. Draw item in the listbox
  73. Arguments:
  74. CRMCListBoxDrawStruct & ds : Input data structure
  75. Return Value:
  76. N/A
  77. --*/
  78. {
  79. CBackupFile * p = (CBackupFile *)ds.m_ItemData;
  80. ASSERT_READ_PTR(p);
  81. DrawBitmap(ds, 0, 0);
  82. CString strVersion;
  83. strVersion.Format(_T("%ld"), p->QueryVersion());
  84. #define MAXLEN (128)
  85. //
  86. // Convert date and time to local format
  87. //
  88. CTime tm;
  89. p->GetTime(tm);
  90. SYSTEMTIME stm =
  91. {
  92. (WORD)tm.GetYear(),
  93. (WORD)tm.GetMonth(),
  94. (WORD)tm.GetDayOfWeek(),
  95. (WORD)tm.GetDay(),
  96. (WORD)tm.GetHour(),
  97. (WORD)tm.GetMinute(),
  98. (WORD)tm.GetSecond(),
  99. 0 // Milliseconds
  100. };
  101. CString strDate, strTime;
  102. LPTSTR lp = strDate.GetBuffer(MAXLEN);
  103. ::GetDateFormat(
  104. LOCALE_USER_DEFAULT,
  105. DATE_SHORTDATE,
  106. &stm,
  107. NULL,
  108. lp,
  109. MAXLEN
  110. );
  111. strDate.ReleaseBuffer();
  112. lp = strTime.GetBuffer(MAXLEN);
  113. GetTimeFormat(LOCALE_USER_DEFAULT, 0L, &stm, NULL, lp, MAXLEN);
  114. strTime.ReleaseBuffer();
  115. strDate += _T(" ");
  116. strDate += strTime;
  117. if (TRUE == p->m_bIsAutomaticBackupType)
  118. {
  119. // Do automatic backup handling...
  120. // Fix for bug 506444
  121. strVersion = _T("");
  122. ColumnText(ds, 0, TRUE, (LPCTSTR) p->m_csAuotmaticBackupText);
  123. ColumnText(ds, 1, FALSE, strVersion);
  124. ColumnText(ds, 2, FALSE, strDate);
  125. }
  126. else
  127. {
  128. ColumnText(ds, 0, TRUE, (LPCTSTR)p->QueryLocation());
  129. ColumnText(ds, 1, FALSE, strVersion);
  130. ColumnText(ds, 2, FALSE, strDate);
  131. }
  132. }
  133. /* virtual */
  134. BOOL
  135. CBackupsListBox::Initialize()
  136. /*++
  137. Routine Description:
  138. initialize the listbox. Insert the columns
  139. as requested, and lay them out appropriately
  140. Arguments:
  141. None
  142. Return Value:
  143. TRUE if initialized successfully, FALSE otherwise
  144. --*/
  145. {
  146. if (!CHeaderListBox::Initialize())
  147. {
  148. return FALSE;
  149. }
  150. HINSTANCE hInst = AfxGetResourceHandle();
  151. InsertColumn(0, WT_LOCATION, IDS_BACKUP_LOCATION, hInst);
  152. InsertColumn(1, WT_VERSION, IDS_BACKUP_VERSION, hInst);
  153. InsertColumn(2, WT_DATE, IDS_BACKUP_DATE, hInst);
  154. //
  155. // Try to set the widths from the stored registry value,
  156. // otherwise distribute according to column weights specified
  157. //
  158. // if (!SetWidthsFromReg())
  159. // {
  160. DistributeColumns();
  161. // }
  162. return TRUE;
  163. }
  164. //
  165. // Backup file object properties dialog
  166. //
  167. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  168. CBkupPropDlg::CBkupPropDlg(
  169. IN CIISMachine * pMachine,
  170. IN CWnd * pParent OPTIONAL
  171. )
  172. /*++
  173. Routine Description:
  174. Constructor
  175. Arguments:
  176. CIISMachine * pMachine : Machine object
  177. CWnd * pParent : Optional parent window
  178. Return Value:
  179. N/A
  180. --*/
  181. : CDialog(CBkupPropDlg::IDD, pParent),
  182. m_pMachine(pMachine),
  183. m_strName(),
  184. m_strPassword()
  185. {
  186. ASSERT_PTR(m_pMachine);
  187. }
  188. void
  189. CBkupPropDlg::DoDataExchange(
  190. IN CDataExchange * pDX
  191. )
  192. {
  193. CDialog::DoDataExchange(pDX);
  194. //{{AFX_DATA_MAP(CBkupPropDlg)
  195. DDX_Control(pDX, IDC_EDIT_BACKUP_NAME, m_edit_Name);
  196. DDX_Control(pDX, IDC_BACKUP_PASSWORD, m_edit_Password);
  197. DDX_Control(pDX, IDC_BACKUP_PASSWORD_CONFIRM, m_edit_PasswordConfirm);
  198. DDX_Control(pDX, IDC_USE_PASSWORD, m_button_Password);
  199. DDX_Control(pDX, IDOK, m_button_OK);
  200. DDX_Text(pDX, IDC_EDIT_BACKUP_NAME, m_strName);
  201. DDV_MinMaxChars(pDX, m_strName, 1, MD_BACKUP_MAX_LEN - 1);
  202. //}}AFX_DATA_MAP
  203. CString buf = m_strName;
  204. buf.TrimLeft();
  205. buf.TrimRight();
  206. if (pDX->m_bSaveAndValidate && !PathIsValid(buf,FALSE))
  207. {
  208. DDV_ShowBalloonAndFail(pDX, IDS_ERR_BAD_BACKUP_NAME);
  209. }
  210. if (m_button_Password.GetCheck())
  211. {
  212. //DDX_Text(pDX, IDC_BACKUP_PASSWORD, m_strPassword);
  213. DDX_Text_SecuredString(pDX, IDC_BACKUP_PASSWORD, m_strPassword);
  214. //DDV_MinChars(pDX, m_strPassword, MIN_PASSWORD_LENGTH);
  215. DDV_MinChars_SecuredString(pDX, m_strPassword, MIN_PASSWORD_LENGTH);
  216. //DDX_Text(pDX, IDC_BACKUP_PASSWORD_CONFIRM, m_strPasswordConfirm);
  217. DDX_Text_SecuredString(pDX, IDC_BACKUP_PASSWORD_CONFIRM, m_strPasswordConfirm);
  218. //DDV_MinChars(pDX, m_strPasswordConfirm, MIN_PASSWORD_LENGTH);
  219. DDV_MinChars_SecuredString(pDX, m_strPasswordConfirm, MIN_PASSWORD_LENGTH);
  220. }
  221. }
  222. //
  223. // Message Map
  224. //
  225. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  226. BEGIN_MESSAGE_MAP(CBkupPropDlg, CDialog)
  227. //{{AFX_MSG_MAP(CBkupPropDlg)
  228. ON_EN_CHANGE(IDC_EDIT_BACKUP_NAME, OnChangeEditBackupName)
  229. ON_EN_CHANGE(IDC_BACKUP_PASSWORD, OnChangeEditPassword)
  230. ON_EN_CHANGE(IDC_BACKUP_PASSWORD_CONFIRM, OnChangeEditPassword)
  231. ON_BN_CLICKED(IDC_USE_PASSWORD, OnUsePassword)
  232. //}}AFX_MSG_MAP
  233. END_MESSAGE_MAP()
  234. //
  235. // Message Handlers
  236. //
  237. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  238. void
  239. CBkupPropDlg::OnChangeEditBackupName()
  240. /*++
  241. Routine Description:
  242. Backup name edit change notification handler.
  243. Arguments:
  244. None.
  245. Return Value:
  246. None.
  247. --*/
  248. {
  249. BOOL bEnableOK = m_edit_Name.GetWindowTextLength() > 0;
  250. m_button_OK.EnableWindow(bEnableOK);
  251. if (bEnableOK && m_button_Password.GetCheck())
  252. {
  253. m_button_OK.EnableWindow(
  254. m_edit_Password.GetWindowTextLength() >= MIN_PASSWORD_LENGTH
  255. && m_edit_PasswordConfirm.GetWindowTextLength() >= MIN_PASSWORD_LENGTH);
  256. }
  257. }
  258. BOOL
  259. CBkupPropDlg::OnInitDialog()
  260. /*++
  261. Routine Description:
  262. WM_INITDIALOG handler. Initialize the dialog.
  263. Arguments:
  264. None.
  265. Return Value:
  266. TRUE if no focus is to be set automatically, FALSE if the focus
  267. is already set.
  268. --*/
  269. {
  270. CDialog::OnInitDialog();
  271. m_button_OK.EnableWindow(FALSE);
  272. m_button_Password.EnableWindow(HAS_BACKUP_PASSWORD(m_pMachine));
  273. m_button_Password.SetCheck(FALSE);
  274. m_edit_Password.EnableWindow(FALSE);
  275. m_edit_PasswordConfirm.EnableWindow(FALSE);
  276. return TRUE;
  277. }
  278. void
  279. CBkupPropDlg::OnChangeEditPassword()
  280. {
  281. m_button_OK.EnableWindow(
  282. m_edit_Password.GetWindowTextLength() >= MIN_PASSWORD_LENGTH
  283. && m_edit_PasswordConfirm.GetWindowTextLength() >= MIN_PASSWORD_LENGTH
  284. && m_edit_Name.GetWindowTextLength() > 0);
  285. }
  286. void
  287. CBkupPropDlg::OnUsePassword()
  288. {
  289. BOOL bUseIt = m_button_Password.GetCheck();
  290. m_edit_Password.EnableWindow(bUseIt);
  291. m_edit_PasswordConfirm.EnableWindow(bUseIt);
  292. if (bUseIt)
  293. {
  294. OnChangeEditPassword();
  295. }
  296. else
  297. {
  298. OnChangeEditBackupName();
  299. }
  300. }
  301. void
  302. CBkupPropDlg::OnOK()
  303. /*++
  304. Routine Description:
  305. 'OK' button handler -- create the backup.
  306. Arguments:
  307. None
  308. Return Value:
  309. None
  310. --*/
  311. {
  312. if (UpdateData(TRUE))
  313. {
  314. if (m_button_Password.GetCheck() && m_strPassword.Compare(m_strPasswordConfirm) != 0)
  315. {
  316. EditShowBalloon(m_edit_PasswordConfirm.m_hWnd, IDS_PASSWORD_NO_MATCH);
  317. return;
  318. }
  319. BeginWaitCursor();
  320. ASSERT_PTR(m_pMachine);
  321. //
  322. // CODEWORK: Verify impersonation settings
  323. //
  324. CMetaBack mb(m_pMachine->QueryAuthInfo());
  325. CError err(mb.QueryResult());
  326. CString buf = m_strName;
  327. buf.TrimLeft();
  328. buf.TrimRight();
  329. if (err.Succeeded())
  330. {
  331. if (HAS_BACKUP_PASSWORD(m_pMachine))
  332. {
  333. if (m_button_Password.GetCheck())
  334. {
  335. CString csTempPassword;
  336. m_strPassword.CopyTo(csTempPassword);
  337. err = mb.BackupWithPassword(buf, csTempPassword);
  338. }
  339. else
  340. {
  341. if (m_pMachine->QueryMajorVersion() == 5 && m_pMachine->QueryMinorVersion() == 1)
  342. {
  343. // this was done for iis51 winxp, because otherwise it doesn't work
  344. err = mb.BackupWithPassword(buf, _T(""));
  345. }
  346. else
  347. {
  348. // don't call backupwithpassword if there is no password
  349. err = mb.Backup(buf);
  350. }
  351. }
  352. }
  353. else
  354. {
  355. err = mb.Backup(buf);
  356. }
  357. }
  358. EndWaitCursor();
  359. if (err.Failed())
  360. {
  361. m_edit_Name.SetSel(0, -1);
  362. //
  363. // Special error message if IISADMIN just didn't
  364. // like the name.
  365. //
  366. if (err.Win32Error() == ERROR_INVALID_PARAMETER)
  367. {
  368. EditShowBalloon(m_edit_Name.m_hWnd, IDS_BACKUP_BAD_NAME);
  369. m_edit_Name.SetSel(0, -1);
  370. }
  371. else
  372. {
  373. err.MessageBox(m_hWnd);
  374. }
  375. //
  376. // Don't dismiss the dialog
  377. //
  378. return;
  379. }
  380. EndDialog(IDOK);
  381. }
  382. }
  383. //
  384. // Metabase/Restore dialog
  385. //
  386. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  387. CBackupDlg::CBackupDlg(
  388. IN CIISMachine * pMachine,
  389. IN LPCTSTR lpszMachineName,
  390. IN CWnd * pParent OPTIONAL
  391. )
  392. /*++
  393. Routine Description:
  394. Constructor
  395. Arguments:
  396. CIISMachine * pMachine : Machine object
  397. CWnd * pParent : Optional parent window
  398. Return Value:
  399. N/A
  400. --*/
  401. : m_pMachine(pMachine),
  402. m_list_Backups(),
  403. m_ListBoxRes(IDB_BACKUPS, m_list_Backups.nBitmaps),
  404. m_oblBackups(),
  405. m_oblAutoBackups(),
  406. m_fChangedMetabase(FALSE),
  407. m_fServicesRestarted(FALSE),
  408. m_csMachineName(lpszMachineName),
  409. CDialog(CBackupDlg::IDD, pParent)
  410. {
  411. //{{AFX_DATA_INIT(CBackupDlg)
  412. //}}AFX_DATA_INIT
  413. ASSERT_PTR(m_pMachine);
  414. m_list_Backups.AttachResources(&m_ListBoxRes);
  415. }
  416. void
  417. CBackupDlg::DoDataExchange(
  418. IN CDataExchange * pDX
  419. )
  420. /*++
  421. Routine Description:
  422. Initialise/Store control data
  423. Arguments:
  424. CDataExchange * pDX - DDX/DDV control structure
  425. Return Value:
  426. None
  427. --*/
  428. {
  429. CDialog::DoDataExchange(pDX);
  430. //{{AFX_DATA_MAP(CBackupDlg)
  431. DDX_Control(pDX, IDC_BUTTON_RESTORE, m_button_Restore);
  432. DDX_Control(pDX, IDC_BUTTON_DELETE, m_button_Delete);
  433. DDX_Control(pDX, IDOK, m_button_Close);
  434. //}}AFX_DATA_MAP
  435. DDX_Control(pDX, IDC_LIST_BACKUPS, m_list_Backups);
  436. }
  437. void
  438. CBackupDlg::SetControlStates()
  439. /*++
  440. Routine Description:
  441. Setting control states depending on the state of the dialog
  442. Arguments:
  443. None
  444. Return Value:
  445. None
  446. --*/
  447. {
  448. m_button_Restore.EnableWindow(m_list_Backups.GetSelCount() == 1);
  449. BOOL bEnableButton = FALSE;
  450. // if there is only 1 item selected, then check if it's an automatic backup
  451. // you are not allowed to delete automatic backups...
  452. if (m_list_Backups.GetSelCount() > 0)
  453. {
  454. CBackupFile * pItem = NULL;
  455. if (m_list_Backups.GetSelCount() == 1)
  456. {
  457. pItem = GetSelectedListItem();
  458. if (pItem != NULL)
  459. {
  460. if (FALSE == pItem->m_bIsAutomaticBackupType)
  461. {
  462. // check if it's a automatic backup
  463. bEnableButton = TRUE;
  464. }
  465. }
  466. }
  467. else
  468. {
  469. // if it's a multi select
  470. // loop thru and find out if there is at least
  471. // one item in the list that is deletable..
  472. int nSel = 0;
  473. CBackupFile * pItem2 = m_list_Backups.GetNextSelectedItem(&nSel);
  474. while (pItem2 != NULL && nSel != LB_ERR)
  475. {
  476. if (FALSE == pItem2->m_bIsAutomaticBackupType)
  477. {
  478. bEnableButton = TRUE;
  479. break;
  480. }
  481. nSel++;
  482. pItem2 = m_list_Backups.GetNextSelectedItem(&nSel);
  483. }
  484. }
  485. }
  486. m_button_Delete.EnableWindow(bEnableButton);
  487. }
  488. HRESULT
  489. CBackupDlg::EnumerateBackups(
  490. LPCTSTR lpszSelect OPTIONAL
  491. )
  492. /*++
  493. Routine Description:
  494. Enumerate all existing backups, and add them to the listbox
  495. Arguments:
  496. LPCTSTR lpszSelect : Optional item to select
  497. Return Value:
  498. HRESULT
  499. Notes:
  500. The highest version number of the given name (if any) will
  501. be selected.
  502. --*/
  503. {
  504. CWaitCursor wait;
  505. m_list_Backups.SetRedraw(FALSE);
  506. m_list_Backups.ResetContent();
  507. m_oblBackups.RemoveAll();
  508. m_oblAutoBackups.RemoveAll();
  509. int nSel = LB_ERR;
  510. int nItem = 0;
  511. TCHAR szSearchPath[_MAX_PATH];
  512. ASSERT_PTR(m_pMachine);
  513. //
  514. // CODEWORK: Verify impersonation settings
  515. //
  516. // ----------------------------------
  517. //
  518. // Enumerate all Normal Backups...
  519. //
  520. // ----------------------------------
  521. CMetaBack mb(m_pMachine->QueryAuthInfo());
  522. CError err(mb.QueryResult());
  523. if (err.Succeeded())
  524. {
  525. DWORD dwVersion;
  526. FILETIME ft;
  527. TCHAR szPath[MAX_PATH + 1] = _T("");
  528. FOREVER
  529. {
  530. *szPath = _T('\0');
  531. err = mb.Next(&dwVersion, szPath, &ft);
  532. if (err.Failed())
  533. {
  534. break;
  535. }
  536. TRACEEOLID(szPath << " v" << dwVersion);
  537. CBackupFile * pItem = new CBackupFile(szPath, dwVersion, &ft);
  538. if (!pItem)
  539. {
  540. TRACEEOLID("EnumerateBackups: OOM");
  541. err = ERROR_NOT_ENOUGH_MEMORY;
  542. break;
  543. }
  544. m_oblBackups.AddTail(pItem);
  545. }
  546. if (err.Win32Error() == ERROR_NO_MORE_ITEMS)
  547. {
  548. //
  549. // Finished enumeration successfully
  550. //
  551. err.Reset();
  552. }
  553. // Sort the in memory list, before sticking it into the listbox
  554. m_oblBackups.Sort((CObjectPlus::PCOBJPLUS_ORDER_FUNC)&CBackupFile::OrderByDateTime);
  555. // Dump it into the list box
  556. POSITION pos = m_oblBackups.GetHeadPosition();
  557. CBackupFile * pMyEntry = NULL;
  558. nItem = 0;
  559. while(pos)
  560. {
  561. pMyEntry = (CBackupFile *) m_oblBackups.GetNext(pos);
  562. VERIFY(LB_ERR != m_list_Backups.AddItem(pMyEntry));
  563. if (lpszSelect != NULL && lstrcmpi(lpszSelect, pMyEntry->QueryLocation()) == 0)
  564. {
  565. //
  566. // Remember selection for later
  567. //
  568. nSel = nItem;
  569. }
  570. ++nItem;
  571. }
  572. }
  573. // ----------------------------------
  574. //
  575. // Enumerate all Automatic Backups...
  576. //
  577. // ----------------------------------
  578. if (err.Succeeded())
  579. {
  580. if (HAS_BACKUP_HISTORY(m_pMachine))
  581. {
  582. // This only applies to metabase version 6 and bigger.
  583. DWORD dwMajorVersion = 0;
  584. DWORD dwMinorVersion = 0;
  585. FILETIME ft;
  586. TCHAR szPath[MAX_PATH + 1] = _T("");
  587. // make sure counter starts at zero again.
  588. mb.Reset();
  589. FOREVER
  590. {
  591. *szPath = _T('\0');
  592. err = mb.NextHistory(&dwMajorVersion, &dwMinorVersion, szPath, &ft);
  593. if (err.Failed())
  594. {
  595. // We could be denied access to this machine
  596. if (err.Win32Error() == ERROR_ACCESS_DENIED)
  597. {
  598. if (err.Failed())
  599. {
  600. err.AddOverride(REGDB_E_CLASSNOTREG, IDS_ERR_NO_BACKUP_RESTORE);
  601. m_pMachine->DisplayError(err, m_hWnd);
  602. }
  603. err.Reset();
  604. }
  605. break;
  606. }
  607. TRACEEOLID(szPath << " V:" << dwMajorVersion << "v:"<< dwMinorVersion);
  608. CBackupFile * pItem2 = new CBackupFile(szPath, dwMajorVersion, dwMinorVersion, &ft);
  609. if (!pItem2)
  610. {
  611. TRACEEOLID("EnumerateHistory: OOM");
  612. err = ERROR_NOT_ENOUGH_MEMORY;
  613. break;
  614. }
  615. m_oblAutoBackups.AddTail(pItem2);
  616. }
  617. if (err.Win32Error() == ERROR_NO_MORE_ITEMS)
  618. {
  619. //
  620. // Finished enumeration successfully
  621. //
  622. err.Reset();
  623. }
  624. // Sort the in memory list, before sticking it into the listbox
  625. m_oblAutoBackups.Sort((CObjectPlus::PCOBJPLUS_ORDER_FUNC)&CBackupFile::OrderByDateTime);
  626. // Dump it into the list box
  627. POSITION pos = m_oblAutoBackups.GetHeadPosition();
  628. CBackupFile * pMyEntry = NULL;
  629. nItem = 0;
  630. while(pos)
  631. {
  632. pMyEntry = (CBackupFile *) m_oblAutoBackups.GetNext(pos);
  633. VERIFY(LB_ERR != m_list_Backups.AddItem(pMyEntry));
  634. if (lpszSelect != NULL && lstrcmpi(lpszSelect, pMyEntry->QueryLocation()) == 0)
  635. {
  636. //
  637. // Remember selection for later
  638. //
  639. nSel = nItem;
  640. }
  641. ++nItem;
  642. }
  643. }
  644. }
  645. //
  646. // Select item requested if any
  647. //
  648. m_list_Backups.SetCurSel(nSel);
  649. m_list_Backups.SetRedraw(TRUE);
  650. SetControlStates();
  651. return err;
  652. }
  653. //
  654. // Message Map
  655. //
  656. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  657. BEGIN_MESSAGE_MAP(CBackupDlg, CDialog)
  658. //{{AFX_MSG_MAP(CBackupDlg)
  659. ON_BN_CLICKED(IDC_BUTTON_CREATE, OnButtonCreate)
  660. ON_BN_CLICKED(IDC_BUTTON_DELETE, OnButtonDelete)
  661. ON_BN_CLICKED(IDC_BUTTON_RESTORE, OnButtonRestore)
  662. ON_LBN_DBLCLK(IDC_LIST_BACKUPS, OnDblclkListBackups)
  663. ON_LBN_SELCHANGE(IDC_LIST_BACKUPS, OnSelchangeListBackups)
  664. //}}AFX_MSG_MAP
  665. END_MESSAGE_MAP()
  666. //
  667. // Message Handlers
  668. //
  669. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  670. BOOL
  671. CBackupDlg::OnInitDialog()
  672. /*++
  673. Routine Description:
  674. WM_INITDIALOG handler
  675. Arguments:
  676. None
  677. Return Value:
  678. TRUE if successfully initialized, FALSE otherwise.
  679. --*/
  680. {
  681. CDialog::OnInitDialog();
  682. m_list_Backups.Initialize();
  683. CError err(EnumerateBackups());
  684. if (err.Failed())
  685. {
  686. err.AddOverride(REGDB_E_CLASSNOTREG, IDS_ERR_NO_BACKUP_RESTORE);
  687. m_pMachine->DisplayError(err, m_hWnd);
  688. EndDialog(IDCANCEL);
  689. }
  690. return TRUE;
  691. }
  692. void
  693. CBackupDlg::OnButtonCreate()
  694. /*++
  695. Routine Description:
  696. "Create" button handler
  697. Arguments:
  698. None
  699. Return Value:
  700. None
  701. --*/
  702. {
  703. CBkupPropDlg dlg(m_pMachine, this);
  704. if (dlg.DoModal() == IDOK)
  705. {
  706. //
  707. // We can only return OK if the creation worked
  708. // which is done in the properties dialog.
  709. //
  710. EnumerateBackups(dlg.QueryName());
  711. }
  712. }
  713. void
  714. CBackupDlg::OnButtonDelete()
  715. /*++
  716. Routine Description:
  717. "Delete" button handler
  718. Arguments:
  719. None
  720. Return Value:
  721. None
  722. --*/
  723. {
  724. if (!NoYesMessageBox(IDS_CONFIRM_DELETE_ITEMS))
  725. {
  726. //
  727. // Changed his/her mind
  728. //
  729. return;
  730. }
  731. m_list_Backups.SetRedraw(FALSE);
  732. CWaitCursor wait;
  733. ASSERT_PTR(m_pMachine);
  734. //
  735. // CODEWORK: Verify metabase settings
  736. //
  737. CMetaBack mb(m_pMachine->QueryAuthInfo());
  738. CError err(mb.QueryResult());
  739. if (err.Failed())
  740. {
  741. m_pMachine->DisplayError(err, m_hWnd);
  742. return;
  743. }
  744. int nSel = 0;
  745. CBackupFile * pItem;
  746. pItem = m_list_Backups.GetNextSelectedItem(&nSel);
  747. while (pItem != NULL && nSel != LB_ERR)
  748. {
  749. if (TRUE == pItem->m_bIsAutomaticBackupType)
  750. {
  751. // Don't let them delete Automatic backup types!!!
  752. //
  753. // Advance counter to next item (nSel++)
  754. //
  755. nSel++;
  756. }
  757. else
  758. {
  759. TRACEEOLID("Deleting backup "
  760. << pItem->QueryLocation()
  761. << " v"
  762. << pItem->QueryVersion()
  763. );
  764. err = mb.Delete(
  765. pItem->QueryLocation(),
  766. pItem->QueryVersion()
  767. );
  768. if (err.Failed())
  769. {
  770. m_pMachine->DisplayError(err, m_hWnd);
  771. break;
  772. }
  773. m_list_Backups.DeleteString(nSel);
  774. //
  775. // Don't advance counter to account for shift (nSel++)
  776. //
  777. }
  778. pItem = m_list_Backups.GetNextSelectedItem(&nSel);
  779. }
  780. m_list_Backups.SetRedraw(TRUE);
  781. SetControlStates();
  782. //
  783. // Ensure focus is not on a disabled button.
  784. //
  785. m_button_Close.SetFocus();
  786. }
  787. void
  788. CBackupDlg::OnButtonRestore()
  789. /*++
  790. Routine Description:
  791. 'Restore' button handler
  792. Arguments:
  793. None
  794. Return Value:
  795. None
  796. --*/
  797. {
  798. CBackupFile * pItem = GetSelectedListItem();
  799. ASSERT_READ_PTR(pItem);
  800. if (pItem != NULL)
  801. {
  802. if (NoYesMessageBox(IDS_RESTORE_CONFIRM))
  803. {
  804. if (TRUE == pItem->m_bIsAutomaticBackupType)
  805. {
  806. ASSERT_PTR(m_pMachine);
  807. //
  808. // CODEWORK: Verify impersonation settings
  809. //
  810. CMetaBack mb(m_pMachine->QueryAuthInfo());
  811. CError err(mb.QueryResult());
  812. if (err.Succeeded())
  813. {
  814. CWaitCursor wait;
  815. // Set the dwMDFlags to 0 so that it uses the Major/Minor Version. otherwise
  816. // if it's set to 1 then it would grab the latest backup release.
  817. err = mb.RestoreHistoryBackup(NULL, pItem->QueryMajorVersion(), pItem->QueryMinorVersion(), 0);
  818. }
  819. if (err.Succeeded())
  820. {
  821. // Use our own Messagebox function, so we can pass hWnd.
  822. // AfxMessageBox doesn't take hwnd, and will sometimes not work correctly for mb_applmodal
  823. // like if the app doesn't have the focus anymore, the messagebox will not be modal to the dialog
  824. //::AfxMessageBox(IDS_SUCCESS, MB_APPLMODAL | MB_OK | MB_ICONINFORMATION);
  825. DoHelpMessageBox(m_hWnd,IDS_SUCCESS, MB_APPLMODAL | MB_OK | MB_ICONINFORMATION, 0);
  826. m_button_Close.SetFocus();
  827. m_fChangedMetabase = TRUE;
  828. m_fServicesRestarted = FALSE;
  829. }
  830. else
  831. {
  832. err.MessageBox(m_hWnd);
  833. }
  834. }
  835. else
  836. {
  837. ASSERT_PTR(m_pMachine);
  838. //
  839. // CODEWORK: Verify impersonation settings
  840. //
  841. CMetaBack mb(m_pMachine->QueryAuthInfo());
  842. CError err(mb.QueryResult());
  843. if (err.Succeeded())
  844. {
  845. //
  846. // the WAM stuff takes a while
  847. //
  848. CWaitCursor wait;
  849. //
  850. // Restore method will take care of WAM save/recover
  851. //
  852. if (HAS_BACKUP_PASSWORD(m_pMachine))
  853. {
  854. // do this first, then try with blank password...
  855. err = mb.Restore(pItem->QueryLocation(), pItem->QueryVersion());
  856. if (err.Failed())
  857. {
  858. err = mb.RestoreWithPassword(pItem->QueryLocation(), pItem->QueryVersion(), _T(""));
  859. // if this fails it will popup for entering a valid password...
  860. }
  861. }
  862. else
  863. {
  864. err = mb.Restore(pItem->QueryLocation(), pItem->QueryVersion());
  865. }
  866. }
  867. if (err.Win32Error() == ERROR_WRONG_PASSWORD)
  868. {
  869. CBackupPassword dlg(this);
  870. if (dlg.DoModal() == IDOK)
  871. {
  872. CWaitCursor wait;
  873. CString csTempPassword;
  874. dlg.m_password.CopyTo(csTempPassword);
  875. err = mb.RestoreWithPassword(pItem->QueryLocation(), pItem->QueryVersion(), csTempPassword);
  876. if (err.Win32Error() == ERROR_WRONG_PASSWORD)
  877. {
  878. DoHelpMessageBox(m_hWnd,IDS_WRONG_PASSWORD, MB_APPLMODAL | MB_OK | MB_ICONEXCLAMATION, 0);
  879. return;
  880. }
  881. else if (err.Failed())
  882. {
  883. DoHelpMessageBox(m_hWnd,IDS_ERR_CANNOT_RESTORE, MB_APPLMODAL | MB_OK | MB_ICONEXCLAMATION, 0);
  884. return;
  885. }
  886. else
  887. {
  888. // Use our own Messagebox function, so we can pass hWnd.
  889. // AfxMessageBox doesn't take hwnd, and will sometimes not work correctly for mb_applmodal
  890. // like if the app doesn't have the focus anymore, the messagebox will not be modal to the dialog
  891. //::AfxMessageBox(IDS_SUCCESS, MB_APPLMODAL | MB_OK | MB_ICONINFORMATION);
  892. DoHelpMessageBox(m_hWnd,IDS_SUCCESS, MB_APPLMODAL | MB_OK | MB_ICONINFORMATION, 0);
  893. m_button_Close.SetFocus();
  894. m_fChangedMetabase = TRUE;
  895. m_fServicesRestarted = FALSE;
  896. }
  897. }
  898. else
  899. {
  900. return;
  901. }
  902. }
  903. else if (err.Succeeded())
  904. {
  905. // Use our own Messagebox function, so we can pass hWnd.
  906. // AfxMessageBox doesn't take hwnd, and will sometimes not work correctly for mb_applmodal
  907. // like if the app doesn't have the focus anymore, the messagebox will not be modal to the dialog
  908. //::AfxMessageBox(IDS_SUCCESS, MB_APPLMODAL | MB_OK | MB_ICONINFORMATION);
  909. DoHelpMessageBox(m_hWnd,IDS_SUCCESS, MB_APPLMODAL | MB_OK | MB_ICONINFORMATION, 0);
  910. m_button_Close.SetFocus();
  911. m_fChangedMetabase = TRUE;
  912. m_fServicesRestarted = FALSE;
  913. }
  914. else
  915. {
  916. err.MessageBox(m_hWnd);
  917. }
  918. }
  919. // Refresh the list -- since Automatic Backup does some funky stuff
  920. EnumerateBackups();
  921. }
  922. }
  923. }
  924. void
  925. CBackupDlg::OnDblclkListBackups()
  926. /*++
  927. Routine Description:
  928. Backup list "double click" notification handler
  929. Arguments:
  930. None
  931. Return Value:
  932. None
  933. --*/
  934. {
  935. //
  936. // Nothing presents itself as an obvious action here
  937. //
  938. }
  939. void
  940. CBackupDlg::OnSelchangeListBackups()
  941. /*++
  942. Routine Description:
  943. Backup list "selection change" notification handler
  944. Arguments:
  945. None
  946. Return Value:
  947. None
  948. --*/
  949. {
  950. SetControlStates();
  951. }
  952. CBackupPassword::CBackupPassword(CWnd * pParent) :
  953. CDialog(CBackupPassword::IDD, pParent)
  954. {
  955. }
  956. BEGIN_MESSAGE_MAP(CBackupPassword, CDialog)
  957. //{{AFX_MSG_MAP(CBackupPassword)
  958. ON_EN_CHANGE(IDC_BACKUP_PASSWORD, OnChangedPassword)
  959. //}}AFX_MSG_MAP
  960. END_MESSAGE_MAP()
  961. void
  962. CBackupPassword::DoDataExchange(
  963. IN CDataExchange * pDX
  964. )
  965. {
  966. CDialog::DoDataExchange(pDX);
  967. //{{AFX_DATA_MAP(CBackupPassword)
  968. DDX_Control(pDX, IDC_BACKUP_PASSWORD, m_edit);
  969. DDX_Control(pDX, IDOK, m_button_OK);
  970. //DDX_Text(pDX, IDC_BACKUP_PASSWORD, m_password);
  971. DDX_Text_SecuredString(pDX, IDC_BACKUP_PASSWORD, m_password);
  972. //}}AFX_DATA_MAP
  973. }
  974. BOOL
  975. CBackupPassword::OnInitDialog()
  976. {
  977. CDialog::OnInitDialog();
  978. m_button_OK.EnableWindow(FALSE);
  979. // ::SetFocus(GetDlgItem(IDC_BACKUP_PASSWORD)->m_hWnd);
  980. return FALSE;
  981. }
  982. void
  983. CBackupPassword::OnChangedPassword()
  984. {
  985. m_button_OK.EnableWindow(
  986. m_edit.GetWindowTextLength() > 0);
  987. }