870 lines
27 KiB
C++
870 lines
27 KiB
C++
//+---------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation 1996-2001.
|
|
//
|
|
// File: regdlg.cpp
|
|
//
|
|
// Contents: implementation of CRegistryDialog
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#include "stdafx.h"
|
|
#include "wsecmgr.h"
|
|
#include "resource.h"
|
|
#include "util.h"
|
|
#include "servperm.h"
|
|
#include "addobj.h"
|
|
#include "RegDlg.h"
|
|
|
|
#include <accctrl.h>
|
|
#include <aclapi.h>
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CRegistryDialog dialog
|
|
|
|
|
|
CRegistryDialog::CRegistryDialog()
|
|
: CHelpDialog(a177HelpIDs, IDD, 0)
|
|
{
|
|
//{{AFX_DATA_INIT(CRegistryDialog)
|
|
m_strReg = _T("");
|
|
//}}AFX_DATA_INIT
|
|
|
|
m_pConsole = NULL;
|
|
m_pTemplate = NULL;
|
|
m_dbHandle = NULL;
|
|
m_cookie = 0;
|
|
m_pIl = NULL;
|
|
m_pDataObj = NULL;
|
|
m_bNoUpdate = FALSE;
|
|
}
|
|
|
|
void CRegistryDialog::DoDataExchange(CDataExchange* pDX)
|
|
{
|
|
CDialog::DoDataExchange(pDX);
|
|
//{{AFX_DATA_MAP(CRegistryDialog)
|
|
DDX_Control(pDX, IDC_REGTREE, m_tcReg);
|
|
DDX_Text(pDX, IDC_REGKEY, m_strReg);
|
|
//}}AFX_DATA_MAP
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------------------------
|
|
Method: CreateKeyInfo
|
|
|
|
Synopsis: Create a new TI_KEYINFO structure and optionaly set its members
|
|
|
|
Arguments: [hKey] - Optional value to set the hKey member of TI_KEYINFO
|
|
default is zero
|
|
[Enum] - Optional value to set the Enum member of TI_KEYINFO
|
|
default is zero
|
|
Returns: a LPTI_KEYINFO pointer
|
|
---------------------------------------------------------------------------------------------*/
|
|
LPTI_KEYINFO CRegistryDialog::CreateKeyInfo(HKEY hKey, bool Enum)
|
|
{
|
|
|
|
LPTI_KEYINFO pInfo = NULL;
|
|
pInfo = new TI_KEYINFO;
|
|
|
|
if(pInfo){
|
|
pInfo->hKey = hKey;
|
|
pInfo->Enum = Enum;
|
|
}
|
|
return pInfo;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------------------------
|
|
Method: IsValidRegPath
|
|
|
|
Synopsis: Returns true if strReg path. We can't assume that this
|
|
HKEY exists in the current registry. We will only make
|
|
sure that the root node exists and each string in
|
|
between '\'s isn't blank.
|
|
|
|
Arguments: [strReg] - A string represending a registry path
|
|
subkeys are seperated by '\'s
|
|
|
|
Returns: TRUE if strReg is a valid path.
|
|
---------------------------------------------------------------------------------------------*/
|
|
BOOL CRegistryDialog::IsValidRegPath(LPCTSTR strReg)
|
|
{
|
|
ASSERT(this);
|
|
ASSERT(m_tcReg);
|
|
|
|
if(!strReg) return FALSE;
|
|
|
|
int iStr = 0; // Current position in strReg
|
|
CString strCheck; // String to check
|
|
LPTI_KEYINFO pkInfo; // Tree item key info.
|
|
|
|
//
|
|
// Find which root node this registry value is in.
|
|
//
|
|
|
|
while(strReg[iStr] && strReg[iStr] != _T('\\')) iStr++;
|
|
strCheck = strReg;
|
|
strCheck = strCheck.Left(iStr);
|
|
strCheck.MakeUpper();
|
|
|
|
// Get the HKEY value from the tree ctrl
|
|
HTREEITEM hTi = m_tcReg.GetRootItem();
|
|
while(hTi){
|
|
if(m_tcReg.GetItemText(hTi) == strCheck)
|
|
break;
|
|
|
|
hTi = m_tcReg.GetNextItem(hTi, TVGN_NEXT);
|
|
}
|
|
if(hTi == NULL) return FALSE;
|
|
|
|
// Get TI_KEYINFO for this root node
|
|
pkInfo = (LPTI_KEYINFO)m_tcReg.GetItemData(hTi);
|
|
|
|
// This value should never be NULL.
|
|
if(!pkInfo){
|
|
TRACE(TEXT("Tree item TI_KEYINFO is NULL for root node '%s'"), (LPCTSTR)strCheck);
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Check the rest of the string to make sure that string's
|
|
// in between '\'s aren't blank
|
|
//
|
|
while(strReg[iStr]){
|
|
|
|
// Check to make sure that the string item before
|
|
// and after the '\' aren't spaces.
|
|
if(strReg[iStr] == _T('\\')){
|
|
if( strReg[iStr + 1] == _T(' ') ||
|
|
strReg[iStr + 1] == _T('\t') ||
|
|
//strReg[iStr + 1] == 0 ||
|
|
|
|
iStr > 0 &&
|
|
(
|
|
strReg[iStr - 1] == _T(' ') ||
|
|
strReg[iStr - 1] == _T('\t')
|
|
)
|
|
)
|
|
return FALSE;
|
|
}
|
|
iStr++;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------------------------------------------------
|
|
Method: MakePathVisible
|
|
|
|
Synopsis:
|
|
Arguments: [strReg] - A string represending a registry path
|
|
subkeys are seperated by '\'s
|
|
|
|
Returns: TRUE if strReg is a valid path.
|
|
---------------------------------------------------------------------------------------------*/
|
|
void CRegistryDialog::MakePathVisible(LPCTSTR strReg)
|
|
{
|
|
ASSERT(this);
|
|
ASSERT(m_tcReg);
|
|
|
|
if(!strReg) return;
|
|
|
|
int iStr = 0; // Current position in strReg
|
|
CString strCheck; // String to check
|
|
LPTI_KEYINFO pkInfo; // Tree item key info.
|
|
|
|
//
|
|
// Find which root node this registry value is in.
|
|
//
|
|
|
|
while(strReg[iStr] && strReg[iStr] != _T('\\')) iStr++;
|
|
strCheck = strReg;
|
|
strCheck = strCheck.Left(iStr);
|
|
strCheck.MakeUpper();
|
|
|
|
// Get the HKEY value from the tree ctrl
|
|
HTREEITEM hTi = m_tcReg.GetRootItem();
|
|
while(hTi){
|
|
if(m_tcReg.GetItemText(hTi) == strCheck)
|
|
break;
|
|
|
|
hTi = m_tcReg.GetNextItem(hTi, TVGN_NEXT);
|
|
}
|
|
if(hTi == NULL) return;
|
|
|
|
// Get TI_KEYINFO for this root node
|
|
pkInfo = (LPTI_KEYINFO)m_tcReg.GetItemData(hTi);
|
|
|
|
// This value should never be NULL.
|
|
if(!pkInfo){
|
|
TRACE(TEXT("Tree item TI_KEYINFO is NULL for root node '%s'"), (LPCTSTR)strCheck);
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Step through each sub item to see if it exists in the tree control
|
|
//
|
|
int iBegin = iStr + 1;
|
|
int iNotFound = -1;
|
|
|
|
while(strReg[iStr] && hTi){
|
|
iStr++;
|
|
if(strReg[iStr] == _T('\\') || strReg[iStr] == 0){
|
|
CString strItem;
|
|
//
|
|
// Make sure we have tree items we can use.
|
|
//
|
|
EnumerateChildren(hTi);
|
|
|
|
if(strReg[iStr] == 0 && strReg[iStr - 1] == _T('\\'))
|
|
m_tcReg.Expand(hTi, TVE_EXPAND);
|
|
|
|
//
|
|
// Parse out the subkeys name.
|
|
strCheck = strReg;
|
|
strCheck = strCheck.Mid(iBegin, iStr - iBegin);
|
|
|
|
strCheck.MakeUpper();
|
|
iBegin = iStr + 1;
|
|
|
|
//
|
|
// Find child item with this name.
|
|
//
|
|
|
|
hTi = m_tcReg.GetNextItem(hTi, TVGN_CHILD);
|
|
while(hTi){
|
|
strItem = m_tcReg.GetItemText(hTi);
|
|
strItem.MakeUpper();
|
|
|
|
iNotFound = lstrcmpiW(strItem, strCheck);
|
|
if(iNotFound >= 0)
|
|
break;
|
|
|
|
hTi = m_tcReg.GetNextItem(hTi, TVGN_NEXT);
|
|
}
|
|
if(strReg[iStr] != 0 && iNotFound != 0){
|
|
hTi = NULL;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Select and ensure visibility if the path was found
|
|
//
|
|
if(hTi){
|
|
if(strReg[iStr - 1] != _T('\\'))
|
|
m_tcReg.Expand(hTi, TVE_COLLAPSE);
|
|
if(!iNotFound){
|
|
m_tcReg.SelectItem(hTi);
|
|
}
|
|
|
|
m_tcReg.EnsureVisible(hTi);
|
|
}
|
|
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------------------------
|
|
Method: EnumerateChildren
|
|
|
|
Synopsis: Enumerates a HKEY subkey and places them as children of 'hParent'
|
|
|
|
Arguments: [hParent] - HTREEITEM to enumerate.
|
|
|
|
Returns: void
|
|
---------------------------------------------------------------------------------------------*/
|
|
void CRegistryDialog::EnumerateChildren(HTREEITEM hParent)
|
|
{
|
|
ASSERT(this);
|
|
ASSERT(m_tcReg);
|
|
|
|
//
|
|
// We won't enumerate for the root.
|
|
//
|
|
if(!hParent || hParent == TVI_ROOT) return;
|
|
|
|
LPTI_KEYINFO hkeyParent; // Used if the item being expanded has an invalid HKEY value
|
|
LPTI_KEYINFO hkeyThis; // HKEY value of item expanding
|
|
int n = 0; // Counter
|
|
LPTSTR szName; // Used to acquire the name of a HKEY item
|
|
DWORD cchName; // Buffer size of szName
|
|
HTREEITEM hti;
|
|
TV_INSERTSTRUCT tvii;
|
|
TV_ITEM tviNew; // Expanding tree item
|
|
TV_ITEM tvi; // Used to add children to the expanding HTREEITEM
|
|
|
|
|
|
// pNMTreeView->itemNew is the TV_ITEM we're expanding.
|
|
hkeyThis = (LPTI_KEYINFO)m_tcReg.GetItemData(hParent);
|
|
|
|
// Exit if we have an invalid pointer.
|
|
if(!hkeyThis) return;
|
|
|
|
//
|
|
// Allocate buffer for HKEY name
|
|
//
|
|
szName = new TCHAR [200];
|
|
if(!szName) return;
|
|
cchName = 200;
|
|
|
|
//
|
|
// Get item text
|
|
//
|
|
ZeroMemory(&tviNew,sizeof(tviNew));
|
|
tviNew.hItem = hParent;
|
|
tviNew.mask = TVIF_TEXT;
|
|
tviNew.pszText = szName;
|
|
tviNew.cchTextMax = cchName;
|
|
m_tcReg.GetItem(&tviNew);
|
|
|
|
//
|
|
// Do we have an invalid HKEY value?
|
|
//
|
|
if (!hkeyThis->hKey) {
|
|
|
|
// Get HKEY value of parent
|
|
hti = m_tcReg.GetParentItem(hParent);
|
|
ZeroMemory(&tvi,sizeof(tvi));
|
|
tvi.hItem = hti;
|
|
tvi.mask = TVIF_PARAM;
|
|
m_tcReg.GetItem(&tvi);
|
|
hkeyParent = (LPTI_KEYINFO)tvi.lParam;
|
|
|
|
if(!hkeyParent){
|
|
TRACE(TEXT("Parent of %s has an does not have a valid TI_KEYINFO struct"), (LPCTSTR)tviNew.pszText);
|
|
delete [] szName;
|
|
return;
|
|
}
|
|
|
|
//
|
|
// If we can't open this key then set the parent item
|
|
// to have no children.
|
|
//
|
|
if (ERROR_SUCCESS != RegOpenKeyEx(hkeyParent->hKey,tviNew.pszText,0,KEY_ALL_ACCESS,&(hkeyThis->hKey))) {
|
|
tvi.mask = TVIF_CHILDREN;
|
|
tvi.cChildren = 0;
|
|
m_tcReg.SetItem(&tvi);
|
|
|
|
delete [] szName;
|
|
return;
|
|
}
|
|
//
|
|
// Set the HKEY value for the item
|
|
//
|
|
tvi.hItem = hParent;
|
|
tvi.lParam = (LPARAM) hkeyThis;
|
|
m_tcReg.SetItem(&tvi);
|
|
}
|
|
|
|
//
|
|
// Don't do anything if this item has already been enumerated or
|
|
// does not have a valid TI_KEYINFO structure
|
|
//
|
|
if( !hkeyThis->Enum ){
|
|
hkeyThis->Enum = true;
|
|
|
|
DWORD cSubKeys; // Used when quering for number of children.
|
|
HKEY hKey; // Used To querry sub keys.
|
|
|
|
//
|
|
// Prepare the TV_INSERTSTRUCT
|
|
//
|
|
ZeroMemory(&tvii, sizeof(TV_INSERTSTRUCT));
|
|
tvii.hParent = hParent;
|
|
tvii.hInsertAfter = TVI_LAST;
|
|
tvii.item.mask = TVIF_CHILDREN | TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
|
|
tvii.item.cChildren = 0;
|
|
tvii.item.iImage = CONFIG_REG_IDX;
|
|
tvii.item.iSelectedImage = CONFIG_REG_IDX;
|
|
|
|
//
|
|
// Add subkeys
|
|
//
|
|
while(ERROR_SUCCESS == RegEnumKeyEx(hkeyThis->hKey,n++, szName,&cchName,NULL,NULL,0,NULL)) {
|
|
|
|
// Open the key so we can query it for the count of children
|
|
if (ERROR_SUCCESS == RegOpenKeyEx(hkeyThis->hKey, szName, 0, KEY_ALL_ACCESS, &(hKey))) {
|
|
if(ERROR_SUCCESS == RegQueryInfoKey(hKey, NULL, NULL, 0, &cSubKeys, NULL, NULL, NULL, NULL, NULL, NULL, NULL))
|
|
tvii.item.cChildren = cSubKeys;
|
|
RegCloseKey(hKey);
|
|
}
|
|
else
|
|
tvii.item.cChildren = 0;
|
|
|
|
tvii.item.cchTextMax = cchName;
|
|
tvii.item.pszText = szName;
|
|
tvii.item.lParam = (LPARAM)CreateKeyInfo(0, false);
|
|
|
|
m_tcReg.InsertItem(&tvii);
|
|
cchName = 200;
|
|
}
|
|
|
|
//
|
|
// Sort children
|
|
//
|
|
m_tcReg.SortChildren(hParent);
|
|
}
|
|
|
|
delete [] szName;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------------------------
|
|
Method: SetProfileInfo
|
|
|
|
Synopsis: Sets either m_pTemplate;
|
|
|
|
Arguments: [pspi] - the PEDITTEMPLATE to save the results in
|
|
[ft] - Type of pointer 'pspi' is (unused)
|
|
returns: void
|
|
---------------------------------------------------------------------------------------------*/
|
|
void CRegistryDialog::SetProfileInfo(PEDITTEMPLATE pspi, FOLDER_TYPES ft)
|
|
{
|
|
m_pTemplate = (PEDITTEMPLATE)pspi;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------------------------
|
|
Method: SetConsole
|
|
|
|
Synopsis: Sets class variable 'm_pConsole'
|
|
|
|
returns: void
|
|
---------------------------------------------------------------------------------------------*/
|
|
void CRegistryDialog::SetConsole(LPCONSOLE pConsole)
|
|
{
|
|
m_pConsole = pConsole;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------------------------
|
|
Method: SetComponentData
|
|
|
|
Synopsis: Sets class varaible 'm_pComponentData'
|
|
|
|
returns: void
|
|
---------------------------------------------------------------------------------------------*/
|
|
void CRegistryDialog::SetComponentData(CComponentDataImpl *pComponentData)
|
|
{
|
|
m_pComponentData = pComponentData;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------------------------
|
|
Method: SetCookie
|
|
|
|
Synopsis: Sets class variable 'm_cookie'
|
|
|
|
returns: void
|
|
---------------------------------------------------------------------------------------------*/
|
|
void CRegistryDialog::SetCookie(MMC_COOKIE cookie)
|
|
{
|
|
m_cookie = cookie;
|
|
}
|
|
|
|
|
|
BEGIN_MESSAGE_MAP(CRegistryDialog, CHelpDialog)
|
|
//{{AFX_MSG_MAP(CRegistryDialog)
|
|
ON_NOTIFY(TVN_ITEMEXPANDING, IDC_REGTREE, OnItemexpandingRegtree)
|
|
ON_NOTIFY(TVN_DELETEITEM, IDC_REGTREE, OnDeleteitemRegtree)
|
|
ON_NOTIFY(TVN_SELCHANGED, IDC_REGTREE, OnSelchangedRegtree)
|
|
ON_EN_CHANGE(IDC_REGKEY, OnChangeRegkey)
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CRegistryDialog message handlers
|
|
|
|
/*-------------------------------------------------------------------------------------------
|
|
Method: OnOK
|
|
|
|
Synopsis: Message handler for the IDOK button,
|
|
|
|
**BUG** Creating the new configuration item should happen outside of
|
|
the dialog.
|
|
|
|
Returns: void
|
|
---------------------------------------------------------------------------------------------*/
|
|
void CRegistryDialog::OnOK()
|
|
{
|
|
UpdateData(TRUE);
|
|
|
|
|
|
if (!m_strReg.IsEmpty()) {
|
|
|
|
int nCont=0;
|
|
CFolder *pFolder = (CFolder *)m_cookie;
|
|
|
|
if ( m_cookie && AREA_REGISTRY_ANALYSIS == pFolder->GetType() ) {
|
|
//
|
|
// add a key to analysis area
|
|
//
|
|
if ( m_dbHandle ) {
|
|
nCont = 1;
|
|
}
|
|
|
|
} else if ( m_pTemplate && m_pTemplate->pTemplate ) {
|
|
|
|
nCont = 2;
|
|
//
|
|
// if no object is in the buffer, create it with count = 0
|
|
// this buffer will be freed when the template is freed
|
|
//
|
|
if ( !m_pTemplate->pTemplate->pRegistryKeys.pAllNodes ) {
|
|
|
|
PSCE_OBJECT_ARRAY pTemp = (PSCE_OBJECT_ARRAY)LocalAlloc(0, sizeof(SCE_OBJECT_ARRAY));
|
|
if ( pTemp ) {
|
|
pTemp->Count = 0;
|
|
pTemp->pObjectArray = NULL;
|
|
m_pTemplate->pTemplate->pRegistryKeys.pAllNodes = pTemp;
|
|
} else
|
|
nCont = 0;
|
|
}
|
|
}
|
|
|
|
HRESULT hr=E_FAIL;
|
|
|
|
if ( nCont ) {
|
|
PSECURITY_DESCRIPTOR pSelSD=NULL;
|
|
SECURITY_INFORMATION SelSeInfo = 0;
|
|
BYTE ConfigStatus = 0;
|
|
|
|
if (m_pComponentData) {
|
|
if ( m_pComponentData->GetAddObjectSecurity(
|
|
GetSafeHwnd(),
|
|
m_strReg,
|
|
TRUE,
|
|
SE_REGISTRY_KEY,
|
|
pSelSD,
|
|
SelSeInfo,
|
|
ConfigStatus
|
|
) == E_FAIL ) {
|
|
return;
|
|
}
|
|
} else {
|
|
return;
|
|
}
|
|
|
|
hr = S_OK;
|
|
|
|
if ( pSelSD && SelSeInfo ) {
|
|
|
|
if ( 1 == nCont ) {
|
|
//
|
|
// add to the engine directly
|
|
//
|
|
SCESTATUS sceStatus=SCESTATUS_SUCCESS;
|
|
BYTE AnalStatus;
|
|
|
|
//
|
|
// start the transaction if it's not started
|
|
//
|
|
if ( m_pComponentData->EngineTransactionStarted() ) {
|
|
|
|
sceStatus = SceUpdateObjectInfo(
|
|
m_dbHandle,
|
|
AREA_REGISTRY_SECURITY,
|
|
(LPTSTR)(LPCTSTR)m_strReg,
|
|
m_strReg.GetLength(), // number of characters
|
|
ConfigStatus,
|
|
TRUE,
|
|
pSelSD,
|
|
SelSeInfo,
|
|
&AnalStatus
|
|
);
|
|
if ( SCESTATUS_SUCCESS == sceStatus ) {
|
|
|
|
hr = m_pComponentData->UpdateScopeResultObject(m_pDataObj,
|
|
m_cookie,
|
|
AREA_REGISTRY_SECURITY);
|
|
|
|
m_pTemplate->SetDirty(AREA_REGISTRY_SECURITY);
|
|
|
|
}
|
|
} else {
|
|
//
|
|
// can't start transaction
|
|
//
|
|
hr = E_FAIL;
|
|
}
|
|
|
|
} else {
|
|
//
|
|
// add to configuration template
|
|
//
|
|
|
|
PSCE_OBJECT_ARRAY poa;
|
|
unsigned int i;
|
|
|
|
poa = m_pTemplate->pTemplate->pRegistryKeys.pAllNodes;
|
|
|
|
// Make sure this key isn't already in the list:
|
|
for (i=0;i < poa->Count;i++) {
|
|
if (lstrcmpi(poa->pObjectArray[i]->Name,m_strReg) == 0) {
|
|
LocalFree(pSelSD);
|
|
return;
|
|
}
|
|
}
|
|
|
|
PSCE_OBJECT_SECURITY *pCopy;
|
|
|
|
// For some reason the LocalReAlloc version of this keeps giving out of memory
|
|
// errors, but allocing & copying everything works fine.
|
|
pCopy = (PSCE_OBJECT_SECURITY *)LocalAlloc(LPTR,(poa->Count+1)*sizeof(PSCE_OBJECT_SECURITY));
|
|
if (pCopy) {
|
|
|
|
for (i=0; i<poa->Count; i++) {
|
|
pCopy[i] = poa->pObjectArray[i];
|
|
}
|
|
|
|
pCopy[poa->Count] = (PSCE_OBJECT_SECURITY) LocalAlloc(LPTR,sizeof(SCE_OBJECT_SECURITY));
|
|
if ( pCopy[poa->Count] ) {
|
|
pCopy[poa->Count]->Name = (PWSTR) LocalAlloc(LPTR,(m_strReg.GetLength()+1)*sizeof(TCHAR));
|
|
|
|
if ( pCopy[poa->Count]->Name ) {
|
|
|
|
lstrcpy(pCopy[poa->Count]->Name,m_strReg);
|
|
pCopy[poa->Count]->pSecurityDescriptor = pSelSD;
|
|
pCopy[poa->Count]->SeInfo = SelSeInfo;
|
|
pCopy[poa->Count]->Status = ConfigStatus;
|
|
pCopy[poa->Count]->IsContainer = TRUE;
|
|
|
|
pSelSD = NULL;
|
|
|
|
poa->Count++;
|
|
|
|
if ( poa->pObjectArray ) {
|
|
LocalFree(poa->pObjectArray);
|
|
}
|
|
poa->pObjectArray = pCopy;
|
|
|
|
m_pTemplate->SetDirty(AREA_REGISTRY_SECURITY);
|
|
|
|
((CFolder *)m_cookie)->RemoveAllResultItems();
|
|
m_pConsole->UpdateAllViews(NULL ,m_cookie, UAV_RESULTITEM_UPDATEALL);
|
|
|
|
hr = S_OK;
|
|
|
|
} else {
|
|
LocalFree(pCopy[poa->Count]);
|
|
LocalFree(pCopy);
|
|
}
|
|
} else
|
|
LocalFree(pCopy);
|
|
}
|
|
}
|
|
if ( pSelSD ) {
|
|
LocalFree(pSelSD);
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( FAILED(hr) ) {
|
|
CString str;
|
|
str.LoadString(IDS_CANT_ADD_KEY);
|
|
AfxMessageBox(str);
|
|
}
|
|
}
|
|
|
|
CDialog::OnOK();
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------------------------
|
|
Method: OnInitDialog
|
|
|
|
Synopsis: Create root HKEY entries HKEY_LOCAL_MACHINE, HKEY_CLASSES_ROOT,
|
|
and HKEY_USERS in the tree control.
|
|
|
|
Returns: return TRUE
|
|
---------------------------------------------------------------------------------------------*/
|
|
BOOL CRegistryDialog::OnInitDialog()
|
|
{
|
|
CString strRegKeyName; // Used to load string resources
|
|
// for name of the HTREEITEM
|
|
HTREEITEM hti;
|
|
TV_INSERTSTRUCT tvi;
|
|
|
|
CDialog::OnInitDialog();
|
|
|
|
//
|
|
// Create image list for tree control
|
|
//
|
|
CThemeContextActivator activator; //Bug 424909, Yanggao, 6/29/2001
|
|
m_pIl.Create(IDB_ICON16,16,1,RGB(255,0,255));
|
|
m_tcReg.SetImageList (CImageList::FromHandle (m_pIl), TVSIL_NORMAL);
|
|
|
|
//
|
|
// Add Root HKEY items.
|
|
//
|
|
ZeroMemory(&tvi,sizeof(tvi));
|
|
tvi.hParent = TVI_ROOT;
|
|
tvi.hInsertAfter = TVI_LAST;
|
|
tvi.item.mask = TVIF_CHILDREN | TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
|
|
tvi.item.cChildren = 1; // Initial UI +
|
|
tvi.item.iImage = CONFIG_REG_IDX;
|
|
tvi.item.iSelectedImage = CONFIG_REG_IDX;
|
|
|
|
// Insert HKEY_CLASSES_ROOT
|
|
strRegKeyName.LoadString(IDS_HKCR);
|
|
tvi.item.cchTextMax = strRegKeyName.GetLength()+1;
|
|
tvi.item.pszText = strRegKeyName.LockBuffer();
|
|
tvi.item.lParam = (LPARAM)CreateKeyInfo(HKEY_CLASSES_ROOT, false);
|
|
hti = m_tcReg.InsertItem(&tvi);
|
|
strRegKeyName.UnlockBuffer();
|
|
|
|
// Insert HKEY_LOCAL_MACHINE
|
|
strRegKeyName.LoadString(IDS_HKLM);
|
|
tvi.item.cchTextMax = strRegKeyName.GetLength()+1;
|
|
tvi.item.pszText = strRegKeyName.LockBuffer();
|
|
tvi.item.lParam = (LPARAM)CreateKeyInfo(HKEY_LOCAL_MACHINE, false);
|
|
hti = m_tcReg.InsertItem(&tvi);
|
|
strRegKeyName.UnlockBuffer();
|
|
|
|
// Insert HKEY_USERS
|
|
strRegKeyName.LoadString(IDS_HKU);
|
|
tvi.item.cchTextMax = strRegKeyName.GetLength()+1;
|
|
tvi.item.pszText = strRegKeyName.LockBuffer();
|
|
tvi.item.lParam = (LPARAM)CreateKeyInfo(HKEY_USERS, false);
|
|
hti = m_tcReg.InsertItem(&tvi);
|
|
strRegKeyName.UnlockBuffer();
|
|
|
|
// Sort the tree control
|
|
m_tcReg.SortChildren(NULL);
|
|
return TRUE; // return TRUE unless you set the focus to a control
|
|
// EXCEPTION: OCX Property Pages should return FALSE
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------------------------
|
|
Method: OnItemexpandingRegtree
|
|
|
|
Synopsis: MFC OnNotify TVN_ITEMEXPANDING message handler. The lParam member of
|
|
the HTREEITEM is a pointer to a TI_KEYINFO structure. When
|
|
a tree item is expanded for the first time, we must enumerate all
|
|
its children. The function will set the TI_KEYINFO.Enum = true after
|
|
enumeration.
|
|
|
|
returns: void
|
|
---------------------------------------------------------------------------------------------*/
|
|
void CRegistryDialog::OnItemexpandingRegtree(NMHDR* pNMHDR, LRESULT* pResult)
|
|
{
|
|
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
|
|
|
|
*pResult = 0;
|
|
EnumerateChildren(pNMTreeView->itemNew.hItem);
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------------------------
|
|
Method: OnDeleteitemRegtree
|
|
|
|
Synopsis: MFC OnNotify TVN_DELETEITEM message handler. Delete the TI_KEYINFO
|
|
structure associated with 'itemOld' and close
|
|
the regestry key.
|
|
|
|
returns: void
|
|
---------------------------------------------------------------------------------------------*/
|
|
void CRegistryDialog::OnDeleteitemRegtree(NMHDR* pNMHDR, LRESULT* pResult)
|
|
{
|
|
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
|
|
|
|
LPTI_KEYINFO pInfo = (LPTI_KEYINFO)pNMTreeView->itemOld.lParam;
|
|
if(pInfo){
|
|
|
|
// Close registry key
|
|
if(pInfo->hKey && (INT_PTR)(pInfo->hKey) != -1)
|
|
RegCloseKey(pInfo->hKey);
|
|
|
|
// delete the TI_KEYINFO
|
|
delete pInfo;
|
|
}
|
|
*pResult = 0;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------------------------
|
|
Method: ~CRegistryDialog
|
|
|
|
Synopsis: Release memory used by this class
|
|
|
|
returns: void
|
|
---------------------------------------------------------------------------------------------*/
|
|
CRegistryDialog::~CRegistryDialog()
|
|
{
|
|
m_pIl.Destroy(); //Bug 424909, Yanggao, 6/29/2001
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------------------------
|
|
Method: OnSelchangedRegtree
|
|
|
|
Synopsis: MFC OnNotify TVN_SELCHANGED message handler. Updates 'm_strReg' to
|
|
the full path of the HKEY item
|
|
|
|
returns: void
|
|
---------------------------------------------------------------------------------------------*/
|
|
void CRegistryDialog::OnSelchangedRegtree(NMHDR* pNMHDR, LRESULT* pResult)
|
|
{
|
|
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
|
|
*pResult = 0;
|
|
|
|
//
|
|
// Sometime we don't want to be updated.
|
|
//
|
|
if(m_bNoUpdate) return;
|
|
|
|
TV_ITEM tvi; // Used to get information about tree items
|
|
|
|
CString strSel; // Used to build the path to the selected item
|
|
LPTSTR szBuf; // Name of tree item
|
|
DWORD cchBuf; // size of szBuf
|
|
|
|
cchBuf = 500;
|
|
szBuf = new TCHAR [ cchBuf ];
|
|
if(!szBuf) return;
|
|
|
|
// Get the selected items text
|
|
tvi.hItem = pNMTreeView->itemNew.hItem;
|
|
tvi.mask = TVIF_TEXT | TVIF_PARAM;
|
|
tvi.pszText = szBuf;
|
|
tvi.cchTextMax = cchBuf;
|
|
m_tcReg.GetItem(&tvi);
|
|
|
|
strSel = tvi.pszText;
|
|
|
|
// Retrieve text of all parent items.
|
|
while(tvi.hItem = m_tcReg.GetParentItem(tvi.hItem)) {
|
|
m_tcReg.GetItem(&tvi);
|
|
strSel = L"\\" + strSel;
|
|
strSel = tvi.pszText + strSel;
|
|
}
|
|
|
|
m_strReg = strSel;
|
|
UpdateData(FALSE);
|
|
delete[] szBuf;
|
|
|
|
// Enable the OK button
|
|
if(GetDlgItem(IDOK)) GetDlgItem(IDOK)->EnableWindow(TRUE);
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------------------------
|
|
Method: OnChangeRegkey
|
|
|
|
Synopsis: IDC_REGKEY edit control EN_CHANGE handler.
|
|
|
|
returns: void
|
|
---------------------------------------------------------------------------------------------*/
|
|
void CRegistryDialog::OnChangeRegkey()
|
|
{
|
|
UpdateData(TRUE);
|
|
|
|
if(IsValidRegPath(m_strReg) && GetDlgItem(IDOK)) {
|
|
GetDlgItem(IDOK)->EnableWindow(TRUE);
|
|
|
|
m_bNoUpdate = TRUE;
|
|
MakePathVisible(m_strReg);
|
|
m_bNoUpdate = FALSE;
|
|
}
|
|
else {
|
|
GetDlgItem(IDOK)->EnableWindow(FALSE);
|
|
}
|
|
}
|