📄 registrykey.cpp
字号:
///////////////////////////////////////////////////////////////////////////////
//
// 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 + -