|
|
/*++
Copyright (c) 1994-2000 Microsoft Corporation
Module Name : metaback.cpp
Abstract: Metabase backup and restore dialog
Author: Ronald Meijer (ronaldm) Sergei Antonov (sergeia)
Project: Internet Services Manager
Revision History:
--*/
//
// Include Files
//
#include "stdafx.h"
#include "common.h"
#include "InetMgrApp.h"
#include "iisobj.h"
#include "mddefw.h"
#include "metaback.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__; #endif
//
// CBackupsListBox : a listbox of CBackup objects
//
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
//
// Column width relative weights
//
#define WT_LOCATION 8
#define WT_VERSION 2
#define WT_DATE 6
//
// Registry key name for this dialog
//
const TCHAR g_szRegKey[] = _T("MetaBack");
IMPLEMENT_DYNAMIC(CBackupsListBox, CHeaderListBox);
const int CBackupsListBox::nBitmaps = 1;
#define HAS_BACKUP_PASSWORD(x) \
((x)->QueryMajorVersion() == 5 && (x)->QueryMinorVersion() == 1) || ((x)->QueryMajorVersion() >= 6)
CBackupsListBox::CBackupsListBox() /*++
Routine Description:
Backups listbox constructor
Arguments:
None
Return Value:
N/A
--*/ : CHeaderListBox(HLS_STRETCH, g_szRegKey) { }
void CBackupsListBox::DrawItemEx( IN CRMCListBoxDrawStruct & ds ) /*++
Routine Description:
Draw item in the listbox
Arguments:
CRMCListBoxDrawStruct & ds : Input data structure
Return Value:
N/A
--*/ { CBackupFile * p = (CBackupFile *)ds.m_ItemData; ASSERT_READ_PTR(p);
DrawBitmap(ds, 0, 0);
CString strVersion; strVersion.Format(_T("%ld"), p->QueryVersion());
#define MAXLEN (128)
//
// Convert date and time to local format
//
CTime tm; p->GetTime(tm);
SYSTEMTIME stm = { (WORD)tm.GetYear(), (WORD)tm.GetMonth(), (WORD)tm.GetDayOfWeek(), (WORD)tm.GetDay(), (WORD)tm.GetHour(), (WORD)tm.GetMinute(), (WORD)tm.GetSecond(), 0 // Milliseconds
};
CString strDate, strTime; LPTSTR lp = strDate.GetBuffer(MAXLEN); ::GetDateFormat( LOCALE_USER_DEFAULT, DATE_SHORTDATE, &stm, NULL, lp, MAXLEN ); strDate.ReleaseBuffer();
lp = strTime.GetBuffer(MAXLEN); GetTimeFormat(LOCALE_USER_DEFAULT, 0L, &stm, NULL, lp, MAXLEN); strTime.ReleaseBuffer();
strDate += _T(" "); strDate += strTime;
ColumnText(ds, 0, TRUE, (LPCTSTR)p->QueryLocation()); ColumnText(ds, 1, FALSE, strVersion); ColumnText(ds, 2, FALSE, strDate); }
/* virtual */ BOOL CBackupsListBox::Initialize() /*++
Routine Description:
initialize the listbox. Insert the columns as requested, and lay them out appropriately
Arguments:
None
Return Value:
TRUE if initialized successfully, FALSE otherwise
--*/ { if (!CHeaderListBox::Initialize()) { return FALSE; }
HINSTANCE hInst = AfxGetResourceHandle(); InsertColumn(0, WT_LOCATION, IDS_BACKUP_LOCATION, hInst); InsertColumn(1, WT_VERSION, IDS_BACKUP_VERSION, hInst); InsertColumn(2, WT_DATE, IDS_BACKUP_DATE, hInst);
//
// Try to set the widths from the stored registry value,
// otherwise distribute according to column weights specified
//
// if (!SetWidthsFromReg())
// {
DistributeColumns(); // }
return TRUE; }
//
// Backup file object properties dialog
//
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
CBkupPropDlg::CBkupPropDlg( IN CIISMachine * pMachine, IN CWnd * pParent OPTIONAL ) /*++
Routine Description:
Constructor
Arguments:
CIISMachine * pMachine : Machine object CWnd * pParent : Optional parent window
Return Value:
N/A
--*/ : CDialog(CBkupPropDlg::IDD, pParent), m_pMachine(pMachine), m_strName(), m_strPassword() { ASSERT_PTR(m_pMachine); }
void CBkupPropDlg::DoDataExchange( IN CDataExchange * pDX ) /*++
Routine Description:
Initialise/Store control data
Arguments:
CDataExchange * pDX - DDX/DDV control structure
Return Value:
None
--*/ { CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CBkupPropDlg)
DDX_Control(pDX, IDC_EDIT_BACKUP_NAME, m_edit_Name); DDX_Control(pDX, IDC_BACKUP_PASSWORD, m_edit_Password); DDX_Control(pDX, IDC_BACKUP_PASSWORD_CONFIRM, m_edit_PasswordConfirm); DDX_Control(pDX, IDC_USE_PASSWORD, m_button_Password); DDX_Control(pDX, IDOK, m_button_OK); DDX_Text(pDX, IDC_EDIT_BACKUP_NAME, m_strName); DDV_MaxChars(pDX, m_strName, MD_BACKUP_MAX_LEN - 1); //}}AFX_DATA_MAP
if (m_button_Password.GetCheck()) { DDX_Text(pDX, IDC_BACKUP_PASSWORD, m_strPassword); DDV_MinChars(pDX, m_strPassword, MIN_PASSWORD_LENGTH); DDX_Text(pDX, IDC_BACKUP_PASSWORD_CONFIRM, m_strPasswordConfirm); DDV_MinChars(pDX, m_strPasswordConfirm, MIN_PASSWORD_LENGTH); } }
//
// Message Map
//
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
BEGIN_MESSAGE_MAP(CBkupPropDlg, CDialog) //{{AFX_MSG_MAP(CBkupPropDlg)
ON_EN_CHANGE(IDC_EDIT_BACKUP_NAME, OnChangeEditBackupName) ON_EN_CHANGE(IDC_BACKUP_PASSWORD, OnChangeEditPassword) ON_EN_CHANGE(IDC_BACKUP_PASSWORD_CONFIRM, OnChangeEditPassword) ON_BN_CLICKED(IDC_USE_PASSWORD, OnUsePassword) //}}AFX_MSG_MAP
END_MESSAGE_MAP()
//
// Message Handlers
//
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
void CBkupPropDlg::OnChangeEditBackupName() /*++
Routine Description:
Backup name edit change notification handler.
Arguments:
None.
Return Value:
None.
--*/ { BOOL bEnableOK = m_edit_Name.GetWindowTextLength() > 0; m_button_OK.EnableWindow(bEnableOK); if (bEnableOK && m_button_Password.GetCheck()) { m_button_OK.EnableWindow( m_edit_Password.GetWindowTextLength() >= MIN_PASSWORD_LENGTH && m_edit_PasswordConfirm.GetWindowTextLength() >= MIN_PASSWORD_LENGTH); } }
BOOL CBkupPropDlg::OnInitDialog() /*++
Routine Description:
WM_INITDIALOG handler. Initialize the dialog.
Arguments:
None.
Return Value:
TRUE if no focus is to be set automatically, FALSE if the focus is already set.
--*/ { CDialog::OnInitDialog(); m_button_OK.EnableWindow(FALSE); m_button_Password.EnableWindow(HAS_BACKUP_PASSWORD(m_pMachine)); m_button_Password.SetCheck(FALSE); m_edit_Password.EnableWindow(FALSE); m_edit_PasswordConfirm.EnableWindow(FALSE); return TRUE; }
void CBkupPropDlg::OnChangeEditPassword() { m_button_OK.EnableWindow( m_edit_Password.GetWindowTextLength() >= MIN_PASSWORD_LENGTH && m_edit_PasswordConfirm.GetWindowTextLength() >= MIN_PASSWORD_LENGTH && m_edit_Name.GetWindowTextLength() > 0); }
void CBkupPropDlg::OnUsePassword() { BOOL bUseIt = m_button_Password.GetCheck(); m_edit_Password.EnableWindow(bUseIt); m_edit_PasswordConfirm.EnableWindow(bUseIt); if (bUseIt) { OnChangeEditPassword(); } else { OnChangeEditBackupName(); } }
void CBkupPropDlg::OnOK() /*++
Routine Description:
'OK' button handler -- create the backup.
Arguments:
None
Return Value:
None
--*/ { if (UpdateData(TRUE)) { if (m_button_Password.GetCheck() && m_strPassword.Compare(m_strPasswordConfirm) != 0) { AfxMessageBox(IDS_PASSWORDS_DOESNT_MATCH); return; }
BeginWaitCursor();
ASSERT_PTR(m_pMachine);
//
// CODEWORK: Verify impersonation settings
//
CMetaBack mb(m_pMachine->QueryAuthInfo()); CError err(mb.QueryResult());
if (err.Succeeded()) { if (HAS_BACKUP_PASSWORD(m_pMachine)) { if (m_button_Password.GetCheck()) { err = mb.BackupWithPassword(m_strName, m_strPassword); } else { err = mb.BackupWithPassword(m_strName, _T("")); } } else { err = mb.Backup(m_strName); } }
EndWaitCursor();
if (err.Failed()) { m_edit_Name.SetSel(0, -1); //
// Special error message if IISADMIN just didn't
// like the name.
//
if (err.Win32Error() == ERROR_INVALID_PARAMETER) { ::AfxMessageBox(IDS_BACKUP_BAD_NAME); ((CEdit *)GetDlgItem(IDC_EDIT_BACKUP_NAME))->SetSel(0, -1); } else { err.MessageBox(); } //
// Don't dismiss the dialog
//
return; }
EndDialog(IDOK); } }
//
// Metabase/Restore dialog
//
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
CBackupDlg::CBackupDlg( IN CIISMachine * pMachine, IN CWnd * pParent OPTIONAL ) /*++
Routine Description:
Constructor
Arguments:
CIISMachine * pMachine : Machine object CWnd * pParent : Optional parent window
Return Value:
N/A
--*/ : m_pMachine(pMachine), m_list_Backups(), m_ListBoxRes(IDB_BACKUPS, m_list_Backups.nBitmaps), m_oblBackups(), m_fChangedMetabase(FALSE), CDialog(CBackupDlg::IDD, pParent) { //{{AFX_DATA_INIT(CBackupDlg)
//}}AFX_DATA_INIT
ASSERT_PTR(m_pMachine);
m_list_Backups.AttachResources(&m_ListBoxRes); }
void CBackupDlg::DoDataExchange( IN CDataExchange * pDX ) /*++
Routine Description:
Initialise/Store control data
Arguments:
CDataExchange * pDX - DDX/DDV control structure
Return Value:
None
--*/ { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CBackupDlg)
DDX_Control(pDX, IDC_BUTTON_RESTORE, m_button_Restore); DDX_Control(pDX, IDC_BUTTON_DELETE, m_button_Delete); DDX_Control(pDX, IDOK, m_button_Close); //}}AFX_DATA_MAP
DDX_Control(pDX, IDC_LIST_BACKUPS, m_list_Backups); }
void CBackupDlg::SetControlStates() /*++
Routine Description:
Setting control states depending on the state of the dialog
Arguments:
None
Return Value:
None
--*/ { m_button_Restore.EnableWindow(m_list_Backups.GetSelCount() == 1); m_button_Delete.EnableWindow(m_list_Backups.GetSelCount() > 0); }
HRESULT CBackupDlg::EnumerateBackups( LPCTSTR lpszSelect OPTIONAL ) /*++
Routine Description:
Enumerate all existing backups, and add them to the listbox
Arguments:
LPCTSTR lpszSelect : Optional item to select
Return Value:
HRESULT
Notes:
The highest version number of the given name (if any) will be selected.
--*/ { CWaitCursor wait;
m_list_Backups.SetRedraw(FALSE); m_list_Backups.ResetContent(); m_oblBackups.RemoveAll();
int nSel = LB_ERR;
ASSERT_PTR(m_pMachine);
//
// CODEWORK: Verify impersonation settings
//
CMetaBack mb(m_pMachine->QueryAuthInfo()); CError err(mb.QueryResult());
if (err.Succeeded()) { DWORD dwVersion; FILETIME ft; TCHAR szPath[MAX_PATH + 1] = _T("");
int nItem = 0;
FOREVER { *szPath = _T('\0'); err = mb.Next(&dwVersion, szPath, &ft);
if (err.Failed()) { break; }
TRACEEOLID(szPath << " v" << dwVersion);
CBackupFile * pItem = new CBackupFile(szPath, dwVersion, &ft); if (!pItem) { TRACEEOLID("EnumerateBackups: OOM"); err = ERROR_NOT_ENOUGH_MEMORY; break; }
m_oblBackups.AddTail(pItem); VERIFY(LB_ERR != m_list_Backups.AddItem(pItem));
if (lpszSelect != NULL && lstrcmpi(lpszSelect, szPath) == 0) { //
// Remember selection for later
//
nSel = nItem; }
++nItem; }
if (err.Win32Error() == ERROR_NO_MORE_ITEMS) { //
// Finished enumeration successfully
//
err.Reset(); } }
//
// Select item requested if any
//
m_list_Backups.SetCurSel(nSel); m_list_Backups.SetRedraw(TRUE); SetControlStates();
return err; }
//
// Message Map
//
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
BEGIN_MESSAGE_MAP(CBackupDlg, CDialog) //{{AFX_MSG_MAP(CBackupDlg)
ON_BN_CLICKED(IDC_BUTTON_CREATE, OnButtonCreate) ON_BN_CLICKED(IDC_BUTTON_DELETE, OnButtonDelete) ON_BN_CLICKED(IDC_BUTTON_RESTORE, OnButtonRestore) ON_LBN_DBLCLK(IDC_LIST_BACKUPS, OnDblclkListBackups) ON_LBN_SELCHANGE(IDC_LIST_BACKUPS, OnSelchangeListBackups) //}}AFX_MSG_MAP
END_MESSAGE_MAP()
//
// Message Handlers
//
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
BOOL CBackupDlg::OnInitDialog() /*++
Routine Description:
WM_INITDIALOG handler
Arguments:
None
Return Value:
TRUE if successfully initialized, FALSE otherwise.
--*/ { CDialog::OnInitDialog();
m_list_Backups.Initialize();
CError err(EnumerateBackups());
if (err.Failed()) { err.AddOverride(REGDB_E_CLASSNOTREG, IDS_ERR_NO_BACKUP_RESTORE); m_pMachine->DisplayError(err); EndDialog(IDCANCEL); }
return TRUE; }
void CBackupDlg::OnButtonCreate() /*++
Routine Description:
"Create" button handler
Arguments:
None
Return Value:
None
--*/ { CBkupPropDlg dlg(m_pMachine, this);
if (dlg.DoModal() == IDOK) { //
// We can only return OK if the creation worked
// which is done in the properties dialog.
//
EnumerateBackups(dlg.QueryName()); } }
void CBackupDlg::OnButtonDelete() /*++
Routine Description:
"Delete" button handler
Arguments:
None
Return Value:
None
--*/ { if (!NoYesMessageBox(IDS_CONFIRM_DELETE_ITEMS)) { //
// Changed his mind
//
return; }
m_list_Backups.SetRedraw(FALSE); CWaitCursor wait;
ASSERT_PTR(m_pMachine);
//
// CODEWORK: Verify metabase settings
//
CMetaBack mb(m_pMachine->QueryAuthInfo()); CError err(mb.QueryResult());
if (err.Failed()) { m_pMachine->DisplayError(err); return; }
int nSel = 0; CBackupFile * pItem;
while ((pItem = m_list_Backups.GetNextSelectedItem(&nSel)) != NULL) { TRACEEOLID("Deleting backup " << pItem->QueryLocation() << " v" << pItem->QueryVersion() );
err = mb.Delete( pItem->QueryLocation(), pItem->QueryVersion() );
if (err.Failed()) { m_pMachine->DisplayError(err); break; }
m_list_Backups.DeleteString(nSel);
//
// Don't advance counter to account for shift
//
}
m_list_Backups.SetRedraw(TRUE); SetControlStates();
//
// Ensure focus is not on a disabled button.
//
m_button_Close.SetFocus(); }
void CBackupDlg::OnButtonRestore() /*++
Routine Description:
'Restore' button handler
Arguments:
None
Return Value:
None
--*/ { CBackupFile * pItem = GetSelectedListItem(); ASSERT_READ_PTR(pItem);
if (pItem != NULL) { if (NoYesMessageBox(IDS_RESTORE_CONFIRM)) { ASSERT_PTR(m_pMachine);
//
// CODEWORK: Verify impersonation settings
//
CMetaBack mb(m_pMachine->QueryAuthInfo()); CError err(mb.QueryResult());
if (err.Succeeded()) { //
// the WAM stuff takes a while
//
CWaitCursor wait;
//
// Restore method will take care of WAM save/recover
//
if (HAS_BACKUP_PASSWORD(m_pMachine)) { err = mb.RestoreWithPassword(pItem->QueryLocation(), pItem->QueryVersion(), _T("")); } else { err = mb.Restore(pItem->QueryLocation(), pItem->QueryVersion()); } }
if (err.Win32Error() == ERROR_WRONG_PASSWORD) { CBackupPassword dlg(this); if (dlg.DoModal() == IDOK) { CWaitCursor wait; err = mb.RestoreWithPassword(pItem->QueryLocation(), pItem->QueryVersion(), dlg.m_password); if (err.Win32Error() == ERROR_WRONG_PASSWORD) { ::AfxMessageBox( IDS_WRONG_PASSWORD, MB_OK | MB_ICONEXCLAMATION ); return; } else if (err.Failed()) { ::AfxMessageBox( IDS_ERR_CANNOT_RESTORE, MB_OK | MB_ICONEXCLAMATION ); return; } else { ::AfxMessageBox(IDS_SUCCESS, MB_OK | MB_ICONINFORMATION); m_button_Close.SetFocus(); m_fChangedMetabase = TRUE; } } else { return; } } else if (err.Succeeded()) { ::AfxMessageBox(IDS_SUCCESS, MB_OK | MB_ICONINFORMATION); m_button_Close.SetFocus(); m_fChangedMetabase = TRUE; } else { err.MessageBox(); } } } }
void CBackupDlg::OnDblclkListBackups() /*++
Routine Description:
Backup list "double click" notification handler
Arguments:
None
Return Value:
None
--*/ { //
// Nothing presents itself as an obvious action here
//
}
void CBackupDlg::OnSelchangeListBackups() /*++
Routine Description:
Backup list "selection change" notification handler
Arguments:
None
Return Value:
None
--*/ { SetControlStates(); }
CBackupPassword::CBackupPassword(CWnd * pParent) : CDialog(CBackupPassword::IDD, pParent) { }
BEGIN_MESSAGE_MAP(CBackupPassword, CDialog) //{{AFX_MSG_MAP(CBackupPassword)
ON_EN_CHANGE(IDC_BACKUP_PASSWORD, OnChangedPassword) //}}AFX_MSG_MAP
END_MESSAGE_MAP()
void CBackupPassword::DoDataExchange( IN CDataExchange * pDX ) { CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CBackupPassword)
DDX_Control(pDX, IDC_BACKUP_PASSWORD, m_edit); DDX_Control(pDX, IDOK, m_button_OK); DDX_Text(pDX, IDC_BACKUP_PASSWORD, m_password); //}}AFX_DATA_MAP
}
BOOL CBackupPassword::OnInitDialog() { CDialog::OnInitDialog(); m_button_OK.EnableWindow(FALSE); // ::SetFocus(GetDlgItem(IDC_BACKUP_PASSWORD)->m_hWnd);
return FALSE; }
void CBackupPassword::OnChangedPassword() { m_button_OK.EnableWindow( m_edit.GetWindowTextLength() > 0); }
|