📄 registrytree.cpp
字号:
SetError(_T("Cannot delete subkeys(s) of key %s.\nSubkey enumeration failed.\nError %d (%s)\n"),
rKey.GetKeyName(),nError,GetErrorDescription(nError));
return FALSE;
}
if (!blnKeyDeleted)
SetError(_T("The key %s has no subkeys that match %s pattern.\n"),rKey.GetKeyName(),pszKeyPattern);
return blnKeyDeleted;
}
const TCHAR * CRegistryTree::GetErrorDescription(LONG nError)
{
switch(nError)
{
case ERROR_ACCESS_DENIED:
return _T("Access denied");
case ERROR_FILE_NOT_FOUND:
return _T("The system cannot find the key specified");
case ERROR_INTERNAL_ERROR:
return _T("Internal error");
case ERROR_OUTOFMEMORY:
return _T("Out of memory");
default:
return _T("Unknown error");
}
}
void CRegistryTree::SetError(LONG nError)
{
SetError(_T("Error %u (%s)"),nError,GetErrorDescription(nError));
}
void CRegistryTree::SetError(const TCHAR *pszFormat, ...)
{
va_list args;
va_start(args,pszFormat);
if (_vsntprintf(m_ErrorMsg,ERROR_MSG_BUFFER_SIZE,pszFormat,args) < 0)
m_ErrorMsg[ERROR_MSG_BUFFER_SIZE] = 0;
va_end(args);
}
void CRegistryTree::SetInternalError()
{
SetError(_T("Internal Error"));
}
void CRegistryTree::AddErrorDescription(const TCHAR *pszFormat, ...)
{
size_t size = _tcslen(m_ErrorMsg);
if (size < ERROR_MSG_BUFFER_SIZE)
{
TCHAR *pszAdd = m_ErrorMsg+size;
va_list args;
va_start(args,pszFormat);
size = ERROR_MSG_BUFFER_SIZE-size;
if (_vsntprintf(pszAdd,size,pszFormat,args) < 0)
m_ErrorMsg[size] = 0;
va_end(args);
}
}
void CRegistryTree::SetErrorCommandNAOnRoot(const TCHAR *pszCommand)
{
ASSERT(pszCommand);
if (pszCommand)
SetError(_T("%s") COMMAND_NA_ON_ROOT,pszCommand);
else
SetInternalError();
}
BOOL CRegistryTree::InternalChangeCurrentKey(const TCHAR *pszSubkeyName, REGSAM DesiredAccess)
{
size_t size = _tcslen(pszSubkeyName);
TCHAR *pszSubkeyNameBuffer = new TCHAR[size+3];
if (!pszSubkeyNameBuffer)
{
SetError(_T("Cannot open key : %s%s\nError %d (%s)\n"),
GetCurrentPath(),pszSubkeyName,ERROR_OUTOFMEMORY,GetErrorDescription(ERROR_OUTOFMEMORY));
}
_tcscpy(pszSubkeyNameBuffer,pszSubkeyName);
if (size && (pszSubkeyName[0] == _T('\"')) && (pszSubkeyName[size-1] == _T('\"')))
{
pszSubkeyNameBuffer[size-1] = 0;
pszSubkeyName = pszSubkeyNameBuffer+1;
}
if (_tcscmp(pszSubkeyName,_T(".")) == 0)
{
delete pszSubkeyNameBuffer;
return TRUE;
}
if (_tcscmp(pszSubkeyName,_T("..")) == 0)
{
// Up level abstraction
if (m_pCurrentKey->m_Key.IsRoot())
{
// We are on root
ASSERT(m_pCurrentKey->m_pUp == NULL);
SetError(_T("Cannot open key. The root is not child.\n"));
delete pszSubkeyNameBuffer;
return FALSE;
}
ASSERT(m_pCurrentKey->m_pUp);
if (!m_pCurrentKey->m_pUp)
{
SetInternalError();
delete pszSubkeyNameBuffer;
return FALSE;
}
CNode *pNode = m_pCurrentKey;
m_pCurrentKey = m_pCurrentKey->m_pUp;
delete pNode;
delete pszSubkeyNameBuffer;
return TRUE;
}
CNode *pNewKey = new CNode;
if (!pNewKey)
{
SetError(_T("Cannot open key : %s%s\nError %d (%s)\n"),
GetCurrentPath(),pszSubkeyName,ERROR_OUTOFMEMORY,GetErrorDescription(ERROR_OUTOFMEMORY));
delete pszSubkeyNameBuffer;
return FALSE;
}
if (!InternalGetSubkey(pszSubkeyName,DesiredAccess,pNewKey->m_Key))
{
delete pNewKey;
delete pszSubkeyNameBuffer;
return FALSE;
}
pNewKey->m_pUp = m_pCurrentKey;
m_pCurrentKey = pNewKey;
delete pszSubkeyNameBuffer;
return TRUE;
}
BOOL CRegistryTree::InternalGetSubkey(const TCHAR *pszSubkeyName, REGSAM DesiredAccess, CRegistryKey& rKey)
{
LONG nError;
HKEY hNewKey = NULL;
TCHAR *pszSubkeyNameCaseUpdated = NULL;
nError = m_pCurrentKey->m_Key.OpenSubkey(DesiredAccess,pszSubkeyName,hNewKey);
if (nError != ERROR_SUCCESS)
{
SetError(_T("Cannot open key : %s%s\nError %u (%s)\n"),
GetCurrentPath(),pszSubkeyName,nError,GetErrorDescription(nError));
return FALSE;
}
// enum subkeys to find the subkey and get its name in stored case.
DWORD dwMaxSubkeyNameLength;
nError = m_pCurrentKey->m_Key.GetSubkeyNameMaxLength(dwMaxSubkeyNameLength);
if (nError != ERROR_SUCCESS)
goto SkipCaseUpdate;
pszSubkeyNameCaseUpdated = new TCHAR [dwMaxSubkeyNameLength];
m_pCurrentKey->m_Key.InitSubkeyEnumeration(pszSubkeyNameCaseUpdated, dwMaxSubkeyNameLength);
while ((nError = m_pCurrentKey->m_Key.GetNextSubkeyName()) == ERROR_SUCCESS)
if (_tcsicmp(pszSubkeyNameCaseUpdated, pszSubkeyName) == 0)
break;
if (nError != ERROR_SUCCESS)
{
delete pszSubkeyNameCaseUpdated;
pszSubkeyNameCaseUpdated = NULL;
}
SkipCaseUpdate:
HRESULT hr;
ASSERT(hNewKey);
if (pszSubkeyNameCaseUpdated)
{
hr = rKey.Init(hNewKey,GetCurrentPath(),pszSubkeyNameCaseUpdated,DesiredAccess);
if (FAILED(hr))
{
if (hr == (HRESULT)E_OUTOFMEMORY)
SetError(_T("Cannot open key : %s%s\nError %d (%s)\n"),
GetCurrentPath(),pszSubkeyName,ERROR_OUTOFMEMORY,GetErrorDescription(ERROR_OUTOFMEMORY));
else
SetError(_T("Cannot open key : %s%s\nUnknown error\n"), GetCurrentPath(), pszSubkeyName);
goto Abort;
}
delete pszSubkeyNameCaseUpdated;
}
else
{
hr = rKey.Init(hNewKey,GetCurrentPath(),pszSubkeyName,DesiredAccess);
if (FAILED(hr))
{
if (hr == (HRESULT)E_OUTOFMEMORY)
SetError(_T("Cannot open key : %s%s\nError %d (%s)\n"),
GetCurrentPath(),pszSubkeyName,ERROR_OUTOFMEMORY,GetErrorDescription(ERROR_OUTOFMEMORY));
else
SetError(_T("Cannot open key : %s%s\nUnknown error \n"),
GetCurrentPath(),
pszSubkeyName);
goto Abort;
}
}
return TRUE;
Abort:
if (pszSubkeyNameCaseUpdated)
delete pszSubkeyNameCaseUpdated;
if (hNewKey)
{
LONG nError = RegCloseKey(hNewKey);
ASSERT(nError == ERROR_SUCCESS);
}
return FALSE;
}
BOOL CRegistryTree::GetKey(const TCHAR *pszRelativePath, REGSAM DesiredAccess, CRegistryKey& rKey)
{
CRegistryTree Tree(*this);
if (!Tree.ChangeCurrentKey(pszRelativePath))
{
SetError(Tree.GetLastErrorDescription());
return FALSE;
}
if (Tree.m_pCurrentKey->m_Key.IsRoot())
{
HRESULT hr = rKey.InitRoot(m_pszMachineName);
if (FAILED(hr))
{
if (hr == (HRESULT)E_OUTOFMEMORY)
SetError(_T("\nError %d (%s)\n"),
ERROR_OUTOFMEMORY,GetErrorDescription(ERROR_OUTOFMEMORY));
else
SetInternalError();
return FALSE;
}
return TRUE;
}
// open key with desired access
// may be call to DuplicateHandle() is better.
// registry key handles returned by the RegConnectRegistry function cannot be used in a call to DuplicateHandle.
// Get short key name now...
const TCHAR *pszKeyName = Tree.m_pCurrentKey->m_Key.GetKeyName();
if (pszKeyName == NULL)
{
SetInternalError();
return FALSE;
}
size_t size = _tcslen(pszKeyName);
ASSERT(size);
if (!size)
{
SetInternalError();
return FALSE;
}
const TCHAR *pszShortKeyName_ = pszKeyName + size-1;
pszShortKeyName_--; // skip ending backslash
size = 0;
while (pszShortKeyName_ >= pszKeyName)
{
if (*pszShortKeyName_ == _T('\\'))
break;
pszShortKeyName_--;
size++;
}
if (!size || (*pszShortKeyName_ != _T('\\')))
{
ASSERT(FALSE);
SetInternalError();
return FALSE;
}
TCHAR *pszShortKeyName = new TCHAR [size+1];
if (!pszShortKeyName)
{
SetError(ERROR_OUTOFMEMORY);
return FALSE;
}
memcpy(pszShortKeyName,pszShortKeyName_+1,size*sizeof(TCHAR));
pszShortKeyName[size] = 0;
// change to parent key
if (!Tree.InternalChangeCurrentKey(_T(".."),READ_CONTROL))
{
ASSERT(FALSE);
SetInternalError();
return FALSE;
}
// change back to target key
if (!Tree.InternalGetSubkey(pszShortKeyName,DesiredAccess,rKey))
{
SetError(Tree.GetLastErrorDescription());
return FALSE;
}
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -