|
|
/////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 1996-1999 Microsoft Corporation
//
// Module Name:
// RegRepl.cpp
//
// Abstract:
// Implementation of the CRegReplParamsPage class.
//
// Author:
// David Potter (davidp) February 23, 1997
//
// Revision History:
//
// Notes:
//
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "CluAdmX.h"
#include "RegRepl.h"
#include "RegKey.h"
#include "ExtObj.h"
#include "HelpData.h" // for g_rghelpmap*
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__; #endif
/////////////////////////////////////////////////////////////////////////////
// CRegReplParamsPage property page
/////////////////////////////////////////////////////////////////////////////
IMPLEMENT_DYNCREATE(CRegReplParamsPage, CBasePropertyPage)
/////////////////////////////////////////////////////////////////////////////
// Message Maps
BEGIN_MESSAGE_MAP(CRegReplParamsPage, CBasePropertyPage) //{{AFX_MSG_MAP(CRegReplParamsPage)
ON_BN_CLICKED(IDC_PP_REGREPL_PARAMS_ADD, OnAdd) ON_BN_CLICKED(IDC_PP_REGREPL_PARAMS_MODIFY, OnModify) ON_BN_CLICKED(IDC_PP_REGREPL_PARAMS_REMOVE, OnRemove) ON_NOTIFY(LVN_ITEMCHANGED, IDC_PP_REGREPL_PARAMS_LIST, OnItemChanged) ON_NOTIFY(NM_DBLCLK, IDC_PP_REGREPL_PARAMS_LIST, OnDblClkList) //}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
//++
//
// CRegReplParamsPage::CRegReplParamsPage
//
// Routine Description:
// Default constructor.
//
// Arguments:
// None.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
CRegReplParamsPage::CRegReplParamsPage(void) : CBasePropertyPage(g_aHelpIDs_IDD_PP_REGREPL_PARAMETERS, g_aHelpIDs_IDD_WIZ_REGREPL_PARAMETERS) { //{{AFX_DATA_INIT(CRegReplParamsPage)
//}}AFX_DATA_INIT
m_pwszRegKeys = NULL;
m_iddPropertyPage = IDD_PP_REGREPL_PARAMETERS; m_iddWizardPage = IDD_WIZ_REGREPL_PARAMETERS;
} //*** CRegReplParamsPage::CRegReplParamsPage()
/////////////////////////////////////////////////////////////////////////////
//++
//
// CRegReplParamsPage::~CRegReplParamsPage
//
// Routine Description:
// Destructor.
//
// Arguments:
// None.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
CRegReplParamsPage::~CRegReplParamsPage(void) { delete [] m_pwszRegKeys;
} //*** CRegReplParamsPage::~CRegReplParamsPage()
/////////////////////////////////////////////////////////////////////////////
//++
//
// CRegReplParamsPage::HrInit
//
// Routine Description:
// Initialize the page.
//
// Arguments:
// peo [IN OUT] Pointer to the extension object.
// property sheet.
//
// Return Value:
// S_OK Page initialized successfully.
// hr Page failed to initialize.
//
//--
/////////////////////////////////////////////////////////////////////////////
HRESULT CRegReplParamsPage::HrInit(IN OUT CExtObject * peo) { HRESULT _hr; DWORD _sc; CWaitCursor _wc;
do { // Call the base class method.
_hr = CBasePropertyPage::HrInit(peo); if (FAILED(_hr)) break;
ASSERT(m_pwszRegKeys == NULL);
// Read the list of registry keys to replicate.
_sc = ScReadRegKeys(); if (_sc != ERROR_SUCCESS) { CString strPrompt; CString strError; CString strMsg;
AFX_MANAGE_STATE(AfxGetStaticModuleState());
strPrompt.LoadString(IDS_ERROR_READING_REGKEYS); FormatError(strError, _sc); strMsg.Format(_T("%s\n\n%s"), strPrompt, strError); AfxMessageBox(strMsg, MB_OK | MB_ICONEXCLAMATION); } // if: error eading registry keys
} while ( 0 );
return _hr;
} //*** CRegReplParamsPage::HrInit()
/////////////////////////////////////////////////////////////////////////////
//++
//
// CRegReplParamsPage::DoDataExchange
//
// Routine Description:
// Do data exchange between the dialog and the class.
//
// Arguments:
// pDX [IN OUT] Data exchange object
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
void CRegReplParamsPage::DoDataExchange(CDataExchange* pDX) { if (!pDX->m_bSaveAndValidate || !BSaved()) { //{{AFX_DATA_MAP(CRegReplParamsPage)
DDX_Control(pDX, IDC_PP_REGREPL_PARAMS_REMOVE, m_pbRemove); DDX_Control(pDX, IDC_PP_REGREPL_PARAMS_MODIFY, m_pbModify); DDX_Control(pDX, IDC_PP_REGREPL_PARAMS_LIST, m_lcRegKeys); //}}AFX_DATA_MAP
} // if: not saving or haven't saved yet
CBasePropertyPage::DoDataExchange(pDX);
} //*** CRegReplParamsPage::DoDataExchange()
/////////////////////////////////////////////////////////////////////////////
//++
//
// CRegReplParamsPage::OnInitDialog
//
// Routine Description:
// Handler for the WM_INITDIALOG message.
//
// Arguments:
// None.
//
// Return Value:
// TRUE We need the focus to be set for us.
// FALSE We already set the focus to the proper control.
//
//--
/////////////////////////////////////////////////////////////////////////////
BOOL CRegReplParamsPage::OnInitDialog(void) { CBasePropertyPage::OnInitDialog();
// Add the column.
{ CString strColumn;
AFX_MANAGE_STATE(AfxGetStaticModuleState());
strColumn.LoadString(IDS_COLTEXT_REGKEY); m_lcRegKeys.InsertColumn(0, strColumn, LVCFMT_LEFT, 300); } // Add the column
// Display the list of registry keys.
FillList();
// Enable/disable the Modify and Remove buttons.
{ UINT cSelected = m_lcRegKeys.GetSelectedCount();
// If there is an item selected, enable the Modify and Remove buttons.
m_pbModify.EnableWindow((cSelected > 0) ? TRUE : FALSE); m_pbRemove.EnableWindow((cSelected > 0) ? TRUE : FALSE); } // Enable/disable the Modify and Remove buttons
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
} //*** CRegReplParamsPage::OnInitDialog()
/////////////////////////////////////////////////////////////////////////////
//++
//
// CRegReplParamsPage::OnSetActive
//
// Routine Description:
// Handler for the PSN_SETACTIVE message.
//
// Arguments:
// None.
//
// Return Value:
// TRUE Page successfully initialized.
// FALSE Page not initialized.
//
//--
/////////////////////////////////////////////////////////////////////////////
BOOL CRegReplParamsPage::OnSetActive(void) { if (BWizard()) EnableNext(TRUE);
return CBasePropertyPage::OnSetActive();
} //*** CRegReplParamsPage::OnSetActive()
/////////////////////////////////////////////////////////////////////////////
//++
//
// CRegReplParamsPage::BApplyChanges
//
// Routine Description:
// Apply changes made on the page.
//
// Arguments:
// None.
//
// Return Value:
// TRUE Page successfully applied.
// FALSE Error applying page.
//
//--
/////////////////////////////////////////////////////////////////////////////
BOOL CRegReplParamsPage::BApplyChanges(void) { DWORD dwStatus = ERROR_SUCCESS; CWaitCursor wc;
// Add new items.
{ int iitem; CString strItem; LPCWSTR pwszRegKeys; DWORD cbReturned;
for ( iitem = -1 ; (iitem = m_lcRegKeys.GetNextItem(iitem, LVNI_ALL)) != -1 ; ) { strItem = m_lcRegKeys.GetItemText(iitem, 0); pwszRegKeys = PwszRegKeys(); while (*pwszRegKeys != L'\0') { if (strItem.CompareNoCase(pwszRegKeys) == 0) break; pwszRegKeys += lstrlenW(pwszRegKeys) + 1; } // while: more items in the list
if (*pwszRegKeys == L'\0') { dwStatus = ClusterResourceControl( Peo()->PrdResData()->m_hresource, NULL, // hNode
CLUSCTL_RESOURCE_ADD_REGISTRY_CHECKPOINT, (PVOID) (LPCWSTR) strItem, (strItem.GetLength() + 1) * sizeof(WCHAR), NULL, // OutBuffer
0, // OutBufferSize
&cbReturned // BytesReturned
); if ((dwStatus != ERROR_SUCCESS) && (dwStatus != ERROR_ALREADY_EXISTS)) { CString strPrompt; CString strError; CString strMsg;
{ AFX_MANAGE_STATE(AfxGetStaticModuleState()); strPrompt.FormatMessage(IDS_ERROR_ADDING_REGKEY, strItem); }
FormatError(strError, dwStatus); strMsg.Format(_T("%s\n\n%s"), strPrompt, strError); AfxMessageBox(strMsg, MB_OK | MB_ICONEXCLAMATION); return FALSE; } // if: error adding the item
} // if: found a new one
} // for: each item in the list
} // Add new items
// Remove deleted items.
{ int iitem; CString strItem; LPCWSTR pwszRegKeys = PwszRegKeys(); DWORD cbReturned;
while (*pwszRegKeys != L'\0') { for ( iitem = -1 ; (iitem = m_lcRegKeys.GetNextItem(iitem, LVNI_ALL)) != -1 ; ) { strItem = m_lcRegKeys.GetItemText(iitem, 0); if (strItem.CompareNoCase(pwszRegKeys) == 0) break; } // for: all items in the list
if (iitem == -1) { dwStatus = ClusterResourceControl( Peo()->PrdResData()->m_hresource, NULL, // hNode
CLUSCTL_RESOURCE_DELETE_REGISTRY_CHECKPOINT, (PVOID) pwszRegKeys, (lstrlenW(pwszRegKeys) + 1) * sizeof(WCHAR), NULL, // OutBuffer
0, // OutBufferSize
&cbReturned // BytesReturned
); if (dwStatus != ERROR_SUCCESS) { CString strPrompt; CString strError; CString strMsg;
{ AFX_MANAGE_STATE(AfxGetStaticModuleState()); strPrompt.FormatMessage(IDS_ERROR_DELETING_REGKEY, strItem); }
FormatError(strError, dwStatus); strMsg.Format(_T("%s\n\n%s"), strPrompt, strError); AfxMessageBox(strMsg, MB_OK | MB_ICONEXCLAMATION); return FALSE; } // if: error adding the item
} // if: key was deleted
pwszRegKeys += lstrlenW(pwszRegKeys) + 1; } // while: more strings
} // Remove deleted items
// Re-read the keys.
ScReadRegKeys(); FillList();
return CBasePropertyPage::BApplyChanges();
} //*** CRegReplParamsPage::BApplyChanges()
/////////////////////////////////////////////////////////////////////////////
//++
//
// CRegReplParamsPage::OnAdd
//
// Routine Description:
// Handler for the BN_CLICKED message on the Add button.
//
// Arguments:
// None.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
void CRegReplParamsPage::OnAdd(void) { INT_PTR idReturn; CEditRegKeyDlg dlg(this);
AFX_MANAGE_STATE(AfxGetStaticModuleState());
idReturn = dlg.DoModal(); if (idReturn == IDOK) { m_lcRegKeys.InsertItem(m_lcRegKeys.GetItemCount(), dlg.m_strRegKey); m_lcRegKeys.SetFocus(); SetModified(TRUE); } // if: user accepted the dialog
} //*** CRegReplParamsPage::OnAdd()
/////////////////////////////////////////////////////////////////////////////
//++
//
// CRegReplParamsPage::OnModify
//
// Routine Description:
// Handler for the BN_CLICKED message on the Modify button.
//
// Arguments:
// None.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
void CRegReplParamsPage::OnModify(void) { int iSelectedItem; INT_PTR idReturn; CEditRegKeyDlg dlg(this);
// Set the text in the dialog to the text of the selected item.
iSelectedItem = m_lcRegKeys.GetNextItem(-1, LVNI_SELECTED); ASSERT(iSelectedItem != -1); dlg.m_strRegKey = m_lcRegKeys.GetItemText(iSelectedItem, 0);
AFX_MANAGE_STATE(AfxGetStaticModuleState());
// Display the dialog.
idReturn = dlg.DoModal(); if (idReturn == IDOK) { m_lcRegKeys.SetItemText(iSelectedItem, 0, dlg.m_strRegKey); m_lcRegKeys.SetFocus(); SetModified(TRUE); } // if: user accepted the dialog
} //*** CRegReplParamsPage::OnModify()
/////////////////////////////////////////////////////////////////////////////
//++
//
// CRegReplParamsPage::OnRemove
//
// Routine Description:
// Handler for the BN_CLICKED message on the Remove button.
//
// Arguments:
// None.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
void CRegReplParamsPage::OnRemove(void) { int iSelectedItem;
iSelectedItem = m_lcRegKeys.GetNextItem(-1, LVNI_SELECTED); ASSERT(iSelectedItem != -1); m_lcRegKeys.DeleteItem(iSelectedItem); SetModified(TRUE);
} //*** CRegReplParamsPage::OnRemove()
/////////////////////////////////////////////////////////////////////////////
//++
//
// CRegReplParamsPage::OnItemChanged
//
// Routine Description:
// Handler for the LVN_ITEM_CHANGED message on the list.
//
// Arguments:
// None.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
void CRegReplParamsPage::OnItemChanged(NMHDR * pNMHDR, LRESULT * pResult) { NM_LISTVIEW * pNMListView = (NM_LISTVIEW *) pNMHDR;
// If the selection changed, enable/disable the Properties button.
if ((pNMListView->uChanged & LVIF_STATE) && ((pNMListView->uOldState & LVIS_SELECTED) || (pNMListView->uNewState & LVIS_SELECTED))) { UINT cSelected = m_lcRegKeys.GetSelectedCount();
// If there is an item selected, enable the Modify and Remove buttons.
m_pbModify.EnableWindow((cSelected > 0) ? TRUE : FALSE); m_pbRemove.EnableWindow((cSelected > 0) ? TRUE : FALSE); } // if: selection changed
*pResult = 0;
} //*** CRegReplParamsPage::OnItemChanged()
/////////////////////////////////////////////////////////////////////////////
//++
//
// CRegReplParamsPage::OnDblClkList
//
// Routine Description:
// Handler for the NM_DBLCLK message on the list.
//
// Arguments:
// None.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
void CRegReplParamsPage::OnDblClkList(NMHDR * pNMHDR, LRESULT * pResult) { OnModify(); *pResult = 0;
} //*** CRegReplParamsPage::OnDblClkList()
/////////////////////////////////////////////////////////////////////////////
//++
//
// CRegReplParamsPage::ScReadRegKeys
//
// Routine Description:
// Read the registry keys.
//
// Arguments:
// None.
//
// Return Value:
// ERROR_SUCCESS Registry keys read successfully.
//
//--
/////////////////////////////////////////////////////////////////////////////
DWORD CRegReplParamsPage::ScReadRegKeys(void) { DWORD dwStatus = ERROR_SUCCESS; DWORD cbRegKeys = 256; LPWSTR pwszRegKeys = NULL; CWaitCursor wc; CMemoryException me(FALSE /*bAutoDelete*/, 0 /*nResourceID*/);
// Read the list of registry keys to replicate.
try { // Get registry keys.
pwszRegKeys = new WCHAR[cbRegKeys / sizeof(WCHAR)]; if (pwszRegKeys == NULL) { throw &me; } // if: error allocating key name buffer
dwStatus = ClusterResourceControl( Peo()->PrdResData()->m_hresource, NULL, // hNode
CLUSCTL_RESOURCE_GET_REGISTRY_CHECKPOINTS, NULL, // lpInBuffer
0, // nInBufferSize
pwszRegKeys, cbRegKeys, &cbRegKeys ); if (dwStatus == ERROR_MORE_DATA) { delete [] pwszRegKeys; ASSERT(cbRegKeys == (cbRegKeys / sizeof(WCHAR)) * sizeof(WCHAR)); pwszRegKeys = new WCHAR[cbRegKeys / sizeof(WCHAR)]; if (pwszRegKeys == NULL) { throw &me; } // if: error allocating key name buffer
dwStatus = ClusterResourceControl( Peo()->PrdResData()->m_hresource, NULL, // hNode
CLUSCTL_RESOURCE_GET_REGISTRY_CHECKPOINTS, NULL, // lpInBuffer
0, // nInBufferSize
pwszRegKeys, cbRegKeys, &cbRegKeys ); } // if: buffer too small
} // try
catch (CMemoryException * pme) { pme->ReportError(); pme->Delete(); return ERROR_NOT_ENOUGH_MEMORY; } // catch: CMemoryException
if ((dwStatus != ERROR_SUCCESS) || (cbRegKeys == 0)) *pwszRegKeys = L'\0';
delete [] m_pwszRegKeys; m_pwszRegKeys = pwszRegKeys;
return dwStatus;
} //*** CRegReplParamsPage::ScReadRegKeys()
/////////////////////////////////////////////////////////////////////////////
//++
//
// CRegReplParamsPage::FillList
//
// Routine Description:
// Fill the list control.
//
// Arguments:
// None.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
void CRegReplParamsPage::FillList(void) { m_lcRegKeys.DeleteAllItems();
if (PwszRegKeys() != NULL) { int iitem; int iitemRet; LPCWSTR pwszRegKeys = PwszRegKeys();
for (iitem = 0 ; *pwszRegKeys != L'\0' ; iitem++) { iitemRet = m_lcRegKeys.InsertItem(iitem, pwszRegKeys); ASSERT(iitemRet == iitem); pwszRegKeys += lstrlenW(pwszRegKeys) + 1; } // while: more strings in the list
} // if: there are any keys to display
} //*** CRegReplParamsPage::FillList()
|