⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 registrykey.cpp

📁 Visual C++下的界面设计
💻 CPP
📖 第 1 页 / 共 3 页
字号:
///////////////////////////////////////////////////////////////////////////////
//
// File           : $Workfile:   RegistryKey.cpp  $
// Version        : $Revision:   1.5  $
// Function       : 
//
// Author         : $Author:   len  $
// Date           : $Date:   Oct 25 1998 11:24:38  $
//
// Notes          : 
//
// Modifications  :
//
// $Log:   G:/Documents/JetByte/Source/JetByteTools/Win32Tools/PVCS/RegistryKey.cpv  $
// 
//    Rev 1.5   Oct 25 1998 11:24:38   len
// Tidy up after running Lint...
// 
//    Rev 1.4   Oct 21 1998 20:08:52   len
// Bug fixes as reported by Steve Greenland - steve.greenland@aspentech.com
// 
//    Rev 1.3   Aug 27 1998 07:46:56   len
// Reference counted HKEY and loads of other things.
// 
//    Rev 1.2   Jun 06 1998 07:42:34   Len
// Made delete key reliable. Added DeleteKeyAndSubKeys.
// Tidied up.
// 
//    Rev 1.1   May 25 1998 11:02:40   Len
// Bug fixes.
// 
//    Rev 1.0   May 18 1998 07:49:24   Len
// Initial revision.
// 
///////////////////////////////////////////////////////////////////////////////
//
// Copyright 1998 JetByte Limited.
//
// JetByte Limited grants you ("Licensee") a non-exclusive, royalty free, 
// licence to use, modify and redistribute this software in source and binary 
// code form, provided that i) this copyright notice and licence appear on all 
// copies of the software; and ii) Licensee does not utilize the software in a 
// manner which is disparaging to JetByte Limited.
//
// This software is provided "AS IS," without a warranty of any kind. ALL
// EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING 
// ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE 
// OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBYTE LIMITED AND ITS LICENSORS 
// SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF 
// USING, MODIFYING OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO 
// EVENT WILL JETBYTE LIMITED BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, 
// OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE 
// DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING 
// OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN IF JETBYTE LIMITED 
// HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
//
// This software is not designed or intended for use in on-line control of
// aircraft, air traffic, aircraft navigation or aircraft communications; or in
// the design, construction, operation or maintenance of any nuclear
// facility. Licensee represents and warrants that it will not use or
// redistribute the Software for such purposes.
//
///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////
// Include files
///////////////////////////////////////////////////////////////////////////////

#include "RegistryKey.hpp"

#include <tchar.h>
#include <stdio.h>
#include <malloc.h>

///////////////////////////////////////////////////////////////////////////////
// Namespace: JetByteTools
///////////////////////////////////////////////////////////////////////////////

namespace JetByteTools {

///////////////////////////////////////////////////////////////////////////////
// CRegistryKey
///////////////////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////////////////
// Construction and destruction
///////////////////////////////////////////////////////////////////////////////

CRegistryKey::CRegistryKey(
   HKEY hKey) 
   :  m_pKey(NewCountedKey(hKey, true))
{
}

CRegistryKey::CRegistryKey(
   LPTSTR pRemoteMachine,
   HKEY hKey) 
   :  m_pKey(0)
{
   HKEY theKey = hKey;

   LONG result = RegConnectRegistry(pRemoteMachine, hKey, &theKey);

   if (ERROR_SUCCESS != result)
   {
      throw Exception(_T("CRegistryKey::CRegistryKey() - RegConnectRegistry"), result);
   }

   m_pKey = NewCountedKey(theKey, true);
}


CRegistryKey::CRegistryKey(
   HKEY hKey, 
   LPCTSTR pSubKey, 
   REGSAM samDesired /* = KEY_ALL_ACCESS */,
   LPTSTR pRemoteMachine /* = 0 */)
   :  m_pKey(0)
{
   HKEY theKey = hKey;

   // if we're passed a remote machine name...
   // do a connect registry first

   if (pRemoteMachine)
   {
      LONG result = RegConnectRegistry(pRemoteMachine, hKey, &theKey);

      if (ERROR_SUCCESS != result)
      {
         throw Exception(_T("CRegistryKey::CRegistryKey() - RegConnectRegistry"), result);
      }
   }

   HKEY newKey;

   LONG result = RegOpenKeyEx(theKey, pSubKey, 0, samDesired, &newKey);

   if (ERROR_SUCCESS != result)
   {
      throw Exception(_T("CRegistryKey::CRegistryKey(HKEY hKey ...)"), result);
   }

   m_pKey = NewCountedKey(newKey, true);
}

CRegistryKey::CRegistryKey(const CRegistryKey &rhs)
   :  m_pKey(rhs.m_pKey->AddRef())
{

}

CRegistryKey::~CRegistryKey()
{
   m_pKey = m_pKey->Release();
}

///////////////////////////////////////////////////////////////////////////////
// Assignment
///////////////////////////////////////////////////////////////////////////////

CRegistryKey &CRegistryKey::operator=(const CRegistryKey &rhs)
{
   if (this != &rhs)
   {
      CCountedRegKey *pNewKey = rhs.m_pKey->AddRef();
      
      m_pKey->Release();

      m_pKey = pNewKey;
   }

   return *this;
}

// NOTE: We OWN This hKey from this point on...

CRegistryKey &CRegistryKey::operator=(HKEY hKey)
{
   CCountedRegKey *pNewKey = NewCountedKey(hKey, true);
   
   m_pKey->Release();

   m_pKey = pNewKey;

   return *this;
}

///////////////////////////////////////////////////////////////////////////////
// Static helper function...
///////////////////////////////////////////////////////////////////////////////

CCountedRegKey *CRegistryKey::NewCountedKey(
   HKEY hKey, 
   bool bCloseKeyOnFailure /* = false */)
{
   CCountedRegKey *pCCountedRegKey = 0;

   try
   {
      pCCountedRegKey = new CCountedRegKey(hKey);
   }
   catch (...) //xalloc &e)
   {
      pCCountedRegKey = 0;
   }

   if (!pCCountedRegKey)
   {
      if (bCloseKeyOnFailure)
      {
         RegCloseKey(hKey);
      }

      throw Exception(_T("CRegistryKey::NewCCountedRegKey()"), 
         ERROR_NOT_ENOUGH_MEMORY);
   }

   return pCCountedRegKey;
}

///////////////////////////////////////////////////////////////////////////////
// Registry API wrappers...
///////////////////////////////////////////////////////////////////////////////

CRegistryKey CRegistryKey::OpenKey(
   LPCTSTR pSubKey, 
   REGSAM samDesired /* = KEY_ALL_ACCESS */) const
{
   return CRegistryKey(*this, pSubKey, samDesired);
}

void CRegistryKey::DeleteKey(
   LPCTSTR pKeyName) const 
{
   // Behaviour of RegDeleteKey differs on Win95 and NT
   // On 95 RegDeleteKey will delete keys with subkeys
   // on NT it wont.
   // To add some consistency to the world DeleteKey 
   // will always fail to delete a key with sub keys and
   // DeleteKeyAndSubKeys will always work...


   // scope the key...
   {
      CRegistryKey deadKey = OpenKey(pKeyName); 

      if (deadKey.BeginSubkeyIteration() != deadKey.EndSubkeyIteration())
      {
         throw Exception(_T("CRegistryKey::DeleteKey()"), ERROR_ACCESS_DENIED);
      }
   }

   LONG result = RegDeleteKey(m_pKey->GetCounted(), pKeyName);

   if (ERROR_SUCCESS != result)
   {
      throw Exception(_T("CRegistryKey::DeleteKey()"), result);
   }
}

void CRegistryKey::DeleteKeyAndSubkeys(
   LPCTSTR pKeyName) const 
{
   // Win95 doesn't need this as it deletes subkeys by default
   // NT wont delete a key with subkeys...

   // Scope the deadKey...
   {
      CRegistryKey deadKey = OpenKey(pKeyName);

		// This wont work, we are frigging with the sub keys of the key we're
		// iterating...

//      for (SubkeyIterator it = deadKey.BeginSubkeyIteration();
//         it != deadKey.EndSubkeyIteration();
//        ++it)
//      {
//         deadKey.DeleteKeyAndSubkeys(it.GetName());
//      }

      for (SubkeyIterator it = deadKey.BeginSubkeyIteration();
         it != deadKey.EndSubkeyIteration();
         it = deadKey.BeginSubkeyIteration())
      {
         deadKey.DeleteKeyAndSubkeys(it.GetName());
      }


   }

   DeleteKey(pKeyName);
}

CRegistryKey CRegistryKey::CreateKey(
   LPCTSTR pSubKey, 
   LPTSTR pClass /* = _T("") */, 
   DWORD dwOptions /* = REG_OPTION_NON_VOLATILE */, 
   REGSAM samDesired /* = KEY_ALL_ACCESS */,
   LPSECURITY_ATTRIBUTES pSecurityAttributes /* = NULL */) const
{
   DWORD disposition;

   CRegistryKey key = CreateOrOpenKey(
                        pSubKey,
                        &disposition,
                        pClass,
                        dwOptions,
                        samDesired,
                        pSecurityAttributes);
   
   if (disposition != REG_CREATED_NEW_KEY)
   {
      RegCloseKey(key);

      throw Exception(_T("CRegistryKey::CreateKey()"), ERROR_ALREADY_EXISTS);
   }


   return key;
}

CRegistryKey CRegistryKey::CreateOrOpenKey(
   LPCTSTR pSubKey, 
   DWORD *pDisposition /* = NULL */,
   LPTSTR pClass /* = _T("") */, 
   DWORD dwOptions /* = REG_OPTION_NON_VOLATILE */, 
   REGSAM samDesired /* = KEY_ALL_ACCESS */,
   LPSECURITY_ATTRIBUTES pSecurityAttributes /* = NULL */) const
{
   HKEY hKey;

   DWORD disposition;

   if (!pDisposition)
   {
      pDisposition = &disposition;
   }

   LONG result = RegCreateKeyEx(m_pKey->GetCounted(), pSubKey, 0, pClass, dwOptions,
                           samDesired, pSecurityAttributes, &hKey,
                           pDisposition);

   if (ERROR_SUCCESS != result)
   {
      throw Exception(_T("CRegistryKey::CreateOrOpenKey()"), result);
   }

   return CRegistryKey(hKey);
}

bool CRegistryKey::HasSubkey(
   LPCTSTR pSubKey,    
   REGSAM samDesired /* = KEY_ALL_ACCESS */) const
{
   bool hasKey = false;

   HKEY hKey;

   LONG result = RegOpenKeyEx(m_pKey->GetCounted(), pSubKey, 0, samDesired, &hKey);

   if (ERROR_SUCCESS == result)
   {
      hasKey = true;

      RegCloseKey(hKey);
   }
   else // should check for errors that mean no we dont have it, or we 
      // have it but not with the right access and throw if a real error
   {
      hasKey = false;
   }

   return hasKey;
}

CRegistryKey CRegistryKey::ConnectRegistry(LPTSTR pMachineName) const
{
   HKEY hKey;

   LONG result = RegConnectRegistry(pMachineName, m_pKey->GetCounted(), &hKey);

   if (ERROR_SUCCESS != result)
   {
      throw Exception(_T("CRegistryKey::ConnectRegistry()"), result);
   }

   return CRegistryKey(hKey);
}

void CRegistryKey::FlushKey() const
{
   LONG result = RegFlushKey(m_pKey->GetCounted());

   if (ERROR_SUCCESS != result)
   {
      throw Exception(_T("CRegistryKey::FlushKey()"), result);
   }
}

CRegistryKey::operator HKEY() const 
{ 
   return m_pKey->GetCounted(); 
}

void CRegistryKey::DeleteValue(LPCTSTR pValueName) const
{
   LONG result = RegDeleteValue(m_pKey->GetCounted(), pValueName);

   if (ERROR_SUCCESS != result)
   {
      throw Exception(_T("CRegistryKey::DeleteValue()"), result);
   }
}

// Subkey iteration

CRegistryKey::SubkeyIterator CRegistryKey::BeginSubkeyIteration() const
{
   return SubkeyIterator(m_pKey);
}

CRegistryKey::SubkeyIterator CRegistryKey::EndSubkeyIteration() const
{
   return SubkeyIterator(0);
}
///////////////////////////////////////////////////////////////////////////////
// Value iteration
///////////////////////////////////////////////////////////////////////////////

CRegistryKey::ValueIterator CRegistryKey::BeginValueIteration() const
{
   return ValueIterator(m_pKey);
}

CRegistryKey::ValueIterator CRegistryKey::EndValueIteration() const
{
   return ValueIterator(0);
}

///////////////////////////////////////////////////////////////////////////////
// Query values
///////////////////////////////////////////////////////////////////////////////

bool CRegistryKey::QueryValue(LPCTSTR pValueName, LPBYTE *ppBytes) const
{
   DWORD dwType;
   LPBYTE pBuffer = 0;
   DWORD bufSize = 0;

   bool ok = false;

   LONG result = RegQueryValueEx(
      m_pKey->GetCounted(), 
      pValueName, 
      0,
      &dwType,
      pBuffer,
      &bufSize);

   if (ERROR_SUCCESS != result)
   {
      throw Exception(_T("CRegistryKey::QueryValue()"), result);
   }

   if (dwType == REG_BINARY || dwType == REG_NONE)
   {
      // bufSize should now tell us how much space we need...

		// TODO Smart pointer
		
      pBuffer = (LPBYTE)malloc(bufSize);

      result = RegQueryValueEx(
            m_pKey->GetCounted(), 
            pValueName, 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -