- Start rosapps rearrange and cleanup process.
[reactos.git] / rosapps / sysutils / regexpl / RegistryTree.cpp
diff --git a/rosapps/sysutils/regexpl/RegistryTree.cpp b/rosapps/sysutils/regexpl/RegistryTree.cpp
deleted file mode 100644 (file)
index 75aaaa6..0000000
+++ /dev/null
@@ -1,641 +0,0 @@
-/* $Id$
- *
- * 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)
-  {
-    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;
-}
-