📄 registrytree.cpp
字号:
/* $Id: RegistryTree.cpp 12803 2005-01-04 21:40:25Z narnaoud $
*
* regexpl - Console Registry Explorer
*
* Copyright (C) 2000-2005 Nedko Arnaudov <nedko@users.sourceforge.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
// RegistryTree.cpp: implementation of the CRegistryTree class.
#include "ph.h"
#include "RegistryTree.h"
#include "Pattern.h"
#include "RegistryExplorer.h"
CRegistryTree::CRegistryTree()
{
m_pszMachineName = NULL;
VERIFY(SUCCEEDED(m_Root.m_Key.InitRoot()));
m_Root.m_pUp = NULL;
m_pCurrentKey = &m_Root;
ASSERT(m_pCurrentKey->m_Key.IsRoot());
m_ErrorMsg[ERROR_MSG_BUFFER_SIZE] = 0;
}
CRegistryTree::CRegistryTree(const CRegistryTree& Tree)
{
m_pszMachineName = NULL;
VERIFY(SUCCEEDED(m_Root.m_Key.InitRoot()));
m_Root.m_pUp = NULL;
m_pCurrentKey = &m_Root;
ASSERT(m_pCurrentKey->m_Key.IsRoot());
const TCHAR *pszPath = Tree.GetCurrentPath();
if ((pszPath[0] == _T('\\')) && (pszPath[1] == _T('\\')))
{ // path has machine name
pszPath += 2;
while (*pszPath && (*pszPath != _T('\\')))
pszPath++;
ASSERT(*pszPath == _T('\\')); // if path begins with \\ it must be followed by machine name
}
if (Tree.m_pszMachineName)
SetMachineName(Tree.m_pszMachineName);
VERIFY(ChangeCurrentKey(pszPath));
}
CRegistryTree::~CRegistryTree()
{
if (m_pszMachineName)
delete m_pszMachineName;
CNode *pNode;
while(m_pCurrentKey->m_pUp)
{
pNode = m_pCurrentKey;
m_pCurrentKey = m_pCurrentKey->m_pUp;
delete pNode;
}
// We are on root
ASSERT(m_pCurrentKey->m_Key.IsRoot());
ASSERT(m_pCurrentKey == &m_Root);
}
const TCHAR * CRegistryTree::GetCurrentPath() const
{
return m_pCurrentKey->m_Key.GetKeyName();
}
BOOL CRegistryTree::IsCurrentRoot()
{
return m_pCurrentKey->m_Key.IsRoot();
}
BOOL CRegistryTree::ChangeCurrentKey(const TCHAR *pszRelativePath)
{
if (*pszRelativePath == _T('\\'))
GotoRoot(); // This is full absolute path.
// split path to key names.
TCHAR *pszSeps = _T("\\");
// Make buffer and copy relative path into it.
TCHAR *pszBuffer = new TCHAR[_tcslen(pszRelativePath)+1];
if (!pszBuffer)
{
SetError(ERROR_OUTOFMEMORY);
return FALSE;
}
_tcscpy(pszBuffer,pszRelativePath);
// We accept names in form "\"blablabla\\blab labla\"\\"
size_t size = _tcslen(pszBuffer);
if (size)
{
if (pszBuffer[size-1] == _T('\\'))
pszBuffer[--size] = 0;
TCHAR *psz;
if (*pszBuffer == _T('\"') && (psz = _tcschr(pszBuffer+1,_T('\"'))) && size_t(psz-pszBuffer) == size-1)
{
size--;
pszBuffer[size] = 0;
pszBuffer++;
}
}
TCHAR *pszNewKey = _tcstok(pszBuffer,pszSeps);
if ((!pszNewKey)&&((*pszRelativePath != _T('\\'))||(*(pszRelativePath+1) != 0)))
{
SetError(_T("Invalid key name"));
goto Abort;
};
// change keys
while (pszNewKey)
{
if (!InternalChangeCurrentKey(pszNewKey,KEY_READ))
goto Abort; // InternalChangeCurrentKey sets last error description
// Get next key name
pszNewKey = _tcstok(NULL,pszSeps);
}
return TRUE;
Abort:
delete pszBuffer;
return FALSE;
}
const TCHAR * CRegistryTree::GetLastErrorDescription()
{
return m_ErrorMsg;
}
void CRegistryTree::GotoRoot()
{
// Delete current tree
CNode *pNode;
while(m_pCurrentKey->m_pUp)
{
pNode = m_pCurrentKey;
m_pCurrentKey = m_pCurrentKey->m_pUp;
delete pNode;
}
// We are on root
ASSERT(m_pCurrentKey->m_Key.IsRoot());
ASSERT(m_pCurrentKey == &m_Root);
}
BOOL CRegistryTree::SetMachineName(LPCTSTR pszMachineName)
{
GotoRoot();
// If we are going to local machine...
if (pszMachineName == NULL)
{
// Delete previous machine name buffer if allocated.
if (m_pszMachineName)
delete m_pszMachineName;
m_pszMachineName = NULL;
m_Root.m_Key.InitRoot();
return TRUE;
}
// Skip leading backslashes if any.
while ((*pszMachineName)&&(*pszMachineName == _T('\\')))
pszMachineName++;
ASSERT(*pszMachineName); // No machine name.
TCHAR *pszNewMachineName = new TCHAR[_tcslen(pszMachineName)+3]; // two leading backslashes + terminating null
if (!pszMachineName)
{
SetError(ERROR_OUTOFMEMORY);
return FALSE;
}
// Delete previous machine name buffer if allocated.
if (m_pszMachineName)
delete m_pszMachineName;
m_pszMachineName = pszNewMachineName;
_tcscpy(m_pszMachineName,_T("\\\\")); // leading backslashes
_tcscpy(m_pszMachineName+2,pszMachineName); // machine name itself
_tcsupr(m_pszMachineName+2); // upercase it
VERIFY(SUCCEEDED(m_Root.m_Key.InitRoot(m_pszMachineName)));
return TRUE;
}
BOOL CRegistryTree::NewKey(const TCHAR *pszKeyName, const TCHAR *pszPath, BOOL blnVolatile)
{
if (!m_pCurrentKey)
{
SetErrorCommandNAOnRoot(_T("Creating new key "));
return FALSE;
}
CRegistryTree Tree(*this);
if (!Tree.ChangeCurrentKey(pszPath))
{
SetError(Tree.GetLastErrorDescription());
return FALSE;
}
BOOL blnOpened;
HKEY hKey;
LONG nError = Tree.m_pCurrentKey->m_Key.CreateSubkey(KEY_READ,
pszKeyName,
hKey,
&blnOpened,
blnVolatile);
if (nError == ERROR_SUCCESS)
{
LONG nError = RegCloseKey(hKey);
ASSERT(nError == ERROR_SUCCESS);
}
if ((nError == ERROR_SUCCESS) && blnOpened)
{
SetError(_T("A key \"%s\" already exists."),pszKeyName);
return FALSE;
}
if (nError != ERROR_SUCCESS)
{
SetError(_T("Cannot create key : %s%s\nError %d (%s)\n"),
GetCurrentPath(),pszKeyName,nError,GetErrorDescription(nError));
return FALSE;
}
return TRUE;
}
BOOL CRegistryTree::DeleteSubkeys(const TCHAR *pszKeyPattern, const TCHAR *pszPath, BOOL blnRecursive)
{
CRegistryKey Key;
if (!GetKey(pszPath,KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS|DELETE,Key))
return FALSE;
return DeleteSubkeys(Key, pszKeyPattern, blnRecursive);
}
BOOL CRegistryTree::DeleteSubkeys(CRegistryKey& rKey, const TCHAR *pszKeyPattern, BOOL blnRecursive)
{
LONG nError;
// enumerate subkeys
DWORD dwMaxSubkeyNameLength;
nError = rKey.GetSubkeyNameMaxLength(dwMaxSubkeyNameLength);
if (nError != ERROR_SUCCESS)
{
SetError(_T("Cannot delete subkeys(s) of key %s.\nRequesting info about key failed.\nError %d (%s)\n"),
rKey.GetKeyName(),nError,GetErrorDescription(nError));
return FALSE;
}
TCHAR *pszSubkeyName = new TCHAR [dwMaxSubkeyNameLength];
rKey.InitSubkeyEnumeration(pszSubkeyName, dwMaxSubkeyNameLength);
BOOL blnKeyDeleted = FALSE;
while ((nError = rKey.GetNextSubkeyName()) == ERROR_SUCCESS)
{
if (PatternMatch(pszKeyPattern,pszSubkeyName))
{
if (blnRecursive)
{ // deltion is recursive, delete subkey subkeys
CRegistryKey Subkey;
// open subkey
nError = rKey.OpenSubkey(DELETE,pszSubkeyName,Subkey);
// delete subkey subkeys
if (DeleteSubkeys(Subkey, PATTERN_MATCH_ALL, TRUE))
{
AddErrorDescription(_T("Cannot delete subkey(s) of key %s. Subkey deletion failed.\n"),Subkey.GetKeyName());
return FALSE;
}
}
nError = rKey.DeleteSubkey(pszSubkeyName);
if (nError != ERROR_SUCCESS)
{
SetError(_T("Cannot delete the %s subkey of key %s.\nError %d (%s)\n"),
pszSubkeyName,rKey.GetKeyName(),nError,GetErrorDescription(nError));
return FALSE;
}
blnKeyDeleted = TRUE;
rKey.InitSubkeyEnumeration(pszSubkeyName, dwMaxSubkeyNameLength); // reset iteration
}
}
ASSERT(nError != ERROR_SUCCESS);
if (nError != ERROR_NO_MORE_ITEMS)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -