You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
875 lines
20 KiB
875 lines
20 KiB
//+---------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1997.
|
|
//
|
|
// File: K K R E G . C P P
|
|
//
|
|
// Contents: Windows NT Registry Access Class
|
|
//
|
|
// Notes:
|
|
//
|
|
// Author: kumarp 14 April 97 (09:22:00 pm)
|
|
//
|
|
// Notes:
|
|
// kumarp 1/16/97 most of the code in this file was originally in
|
|
// net\ui\rhino\common\classes\common.h
|
|
// extracted only that portion related to CRegKey & related classes
|
|
// kumarp 3/27/97 the original code used MFC. converted the entire code
|
|
// to make it use STL
|
|
//----------------------------------------------------------------------------
|
|
|
|
#include "pch.h"
|
|
#pragma hdrstop
|
|
#include "kkreg.h"
|
|
#include "kkstl.h"
|
|
#include "kkutils.h"
|
|
#include "nceh.h"
|
|
#include "ncreg.h"
|
|
|
|
HRESULT HrGetRegErrorForTrace(LONG err)
|
|
{
|
|
HRESULT hr = ((err == ERROR_FILE_NOT_FOUND) ||
|
|
(err == ERROR_NO_MORE_ITEMS))
|
|
? S_OK : HRESULT_FROM_WIN32(err);
|
|
|
|
return hr;
|
|
}
|
|
|
|
#define TraceRegFunctionError(e) TraceFunctionError(HrGetRegErrorForTrace(e))
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CORegKey::CORegKey
|
|
//
|
|
// Purpose: constructor for an existing key
|
|
//
|
|
// Arguments: none
|
|
//
|
|
// Author: kumarp 12 April 97 (05:53:03 pm)
|
|
//
|
|
// Notes:
|
|
//
|
|
CORegKey::CORegKey (HKEY hKeyBase,
|
|
PCWSTR pchSubKey,
|
|
REGSAM regSam,
|
|
PCWSTR pchServerName )
|
|
: m_hKey( NULL ),
|
|
m_dwDisposition( 0 ),
|
|
m_fInherit(FALSE)
|
|
{
|
|
DefineFunctionName("CORegKey::CORegKey(HKEY hKeyBase, PCWSTR pchSubKey, )");
|
|
|
|
HKEY hkBase = NULL ;
|
|
LONG err = 0 ;
|
|
|
|
if ( pchServerName )
|
|
{
|
|
// This is a remote connection.
|
|
if ( err = ::RegConnectRegistry( (PWSTR) pchServerName,
|
|
hKeyBase, & hkBase ) )
|
|
{
|
|
TraceLastWin32Error("RegConnectRegistry failed");
|
|
hkBase = NULL ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hkBase = hKeyBase ;
|
|
}
|
|
|
|
if ( err == 0 )
|
|
{
|
|
if ( pchSubKey )
|
|
{
|
|
err = ::RegOpenKeyEx( hkBase, pchSubKey, 0, regSam, & m_hKey ) ;
|
|
/*
|
|
if (err)
|
|
{
|
|
TraceLastWin32Error("RegOpenKeyEx failed");
|
|
}
|
|
*/
|
|
}
|
|
else
|
|
{
|
|
m_hKey = hkBase ;
|
|
hkBase = NULL ;
|
|
m_fInherit = TRUE;
|
|
}
|
|
|
|
if ( hkBase && hkBase != hKeyBase )
|
|
{
|
|
::RegCloseKey( hkBase ) ;
|
|
}
|
|
}
|
|
|
|
if ( err )
|
|
{
|
|
// ReportError( err ) ;
|
|
m_hKey = NULL ;
|
|
}
|
|
|
|
TraceRegFunctionError(err);
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CORegKey::CORegKey
|
|
//
|
|
// Purpose: constructor for creating a new key
|
|
//
|
|
// Arguments: none
|
|
//
|
|
// Author: kumarp 12 April 97 (05:53:03 pm)
|
|
//
|
|
// Notes:
|
|
//
|
|
CORegKey::CORegKey (PCWSTR pchSubKey,
|
|
HKEY hKeyBase,
|
|
DWORD dwOptions,
|
|
REGSAM regSam,
|
|
LPSECURITY_ATTRIBUTES pSecAttr,
|
|
PCWSTR pchServerName)
|
|
: m_hKey( NULL ),
|
|
m_dwDisposition( 0 ),
|
|
m_fInherit(FALSE)
|
|
{
|
|
DefineFunctionName("CORegKey::CORegKey(PCWSTR pchSubKey, HKEY hKeyBase, )");
|
|
|
|
HKEY hkBase = NULL ;
|
|
LONG err = 0;
|
|
|
|
if ( pchServerName )
|
|
{
|
|
// This is a remote connection.
|
|
if ( err = ::RegConnectRegistry( (PWSTR) pchServerName,
|
|
hKeyBase, & hkBase ) )
|
|
{
|
|
hkBase = NULL ;
|
|
TraceLastWin32Error("RegConnectRegistry failed");
|
|
}
|
|
|
|
hkBase = NULL ;
|
|
|
|
}
|
|
else
|
|
{
|
|
hkBase = hKeyBase ;
|
|
}
|
|
|
|
if (err == 0)
|
|
{
|
|
|
|
PCWSTR szEmpty = L"" ;
|
|
|
|
err = ::RegCreateKeyEx( hkBase, pchSubKey,
|
|
0, (PWSTR) szEmpty,
|
|
dwOptions, regSam, pSecAttr,
|
|
& m_hKey,
|
|
& m_dwDisposition ) ;
|
|
|
|
}
|
|
if ( err )
|
|
{
|
|
TraceLastWin32Error("RegCreateKeyEx failed");
|
|
m_hKey = NULL ;
|
|
}
|
|
|
|
TraceRegFunctionError(err);
|
|
}
|
|
|
|
|
|
CORegKey::~CORegKey ()
|
|
{
|
|
if ( m_hKey && !m_fInherit)
|
|
{
|
|
::RegCloseKey( m_hKey ) ;
|
|
}
|
|
}
|
|
|
|
|
|
// Prepare to read a value by finding the value's size.
|
|
LONG CORegKey::PrepareValue (PCWSTR pchValueName,
|
|
DWORD * pdwType,
|
|
DWORD * pcbSize,
|
|
BYTE ** ppbData )
|
|
{
|
|
DefineFunctionName("CORegKey::PrepareValue");
|
|
|
|
LONG err = 0 ;
|
|
|
|
BYTE chDummy[2] ;
|
|
DWORD cbData = 0 ;
|
|
|
|
do
|
|
{
|
|
// Set the resulting buffer size to 0.
|
|
*pcbSize = 0 ;
|
|
*ppbData = NULL ;
|
|
|
|
err = ::RegQueryValueExW( *this,
|
|
(PWSTR) pchValueName,
|
|
0, pdwType,
|
|
chDummy, & cbData ) ;
|
|
|
|
// The only error we should get here is ERROR_MORE_DATA, but
|
|
// we may get no error if the value has no data.
|
|
if ( err == 0 )
|
|
{
|
|
cbData = sizeof (LONG) ; // Just a fudgy number
|
|
}
|
|
else
|
|
if ( err != ERROR_MORE_DATA )
|
|
break ;
|
|
|
|
// Allocate a buffer large enough for the data.
|
|
|
|
*ppbData = new BYTE [ (*pcbSize = cbData) + sizeof (LONG) ] ;
|
|
|
|
if ( *ppbData == NULL )
|
|
{
|
|
err = ERROR_NOT_ENOUGH_MEMORY ;
|
|
break ;
|
|
}
|
|
|
|
// Now that have a buffer, re-fetch the value.
|
|
|
|
err = ::RegQueryValueExW( *this,
|
|
(PWSTR) pchValueName,
|
|
0, pdwType,
|
|
*ppbData, pcbSize ) ;
|
|
|
|
} while ( FALSE ) ;
|
|
|
|
if ( err )
|
|
{
|
|
delete [] *ppbData ;
|
|
}
|
|
|
|
TraceRegFunctionError(err);
|
|
|
|
return err ;
|
|
}
|
|
|
|
// Overloaded value query members; each returns ERROR_INVALID_PARAMETER
|
|
// if data exists but not in correct form to deliver into result object.
|
|
|
|
LONG CORegKey::QueryValue ( PCWSTR pchValueName, tstring& strResult )
|
|
{
|
|
DefineFunctionName("CORegKey::QueryValue(tstring& strResult)");
|
|
|
|
LONG err = 0 ;
|
|
|
|
DWORD dwType ;
|
|
DWORD cbData ;
|
|
BYTE * pabData = NULL ;
|
|
|
|
// strResult.remove();
|
|
strResult = c_szEmpty;
|
|
|
|
do
|
|
{
|
|
if ( err = PrepareValue( pchValueName, & dwType, & cbData, & pabData ) )
|
|
break ;
|
|
|
|
if (( dwType != REG_SZ ) && (dwType != REG_EXPAND_SZ))
|
|
{
|
|
err = ERROR_INVALID_PARAMETER ;
|
|
break ;
|
|
}
|
|
|
|
// Guarantee that the data looks like a string
|
|
pabData[cbData] = 0 ;
|
|
|
|
NC_TRY
|
|
{
|
|
strResult = (PWSTR) pabData ;
|
|
}
|
|
NC_CATCH_BAD_ALLOC
|
|
{
|
|
err = ERROR_NOT_ENOUGH_MEMORY ;
|
|
}
|
|
}
|
|
while ( FALSE ) ;
|
|
|
|
delete [] pabData ;
|
|
|
|
TraceRegFunctionError(err);
|
|
|
|
return err ;
|
|
}
|
|
|
|
LONG CORegKey::QueryValue ( PCWSTR pchValueName, TStringList& strList )
|
|
{
|
|
DefineFunctionName("CORegKey::QueryValue(TStringList& strList)");
|
|
|
|
LONG err = 0 ;
|
|
|
|
DWORD dwType ;
|
|
DWORD cbData ;
|
|
BYTE * pabData = NULL ;
|
|
PWSTR pbTemp, pbTempLimit ;
|
|
|
|
EraseAndDeleteAll(&strList);
|
|
do
|
|
{
|
|
if ( err = PrepareValue( pchValueName, & dwType, & cbData, & pabData ) )
|
|
break ;
|
|
|
|
if ( dwType != REG_MULTI_SZ )
|
|
{
|
|
err = ERROR_INVALID_PARAMETER ;
|
|
break ;
|
|
}
|
|
|
|
// Guarantee that the trailing data looks like a string
|
|
pabData[cbData] = 0 ;
|
|
pbTemp = (PWSTR) pabData ;
|
|
//kumarp: changed the following because it gives wrong results for UNICODE
|
|
// pbTempLimit = & pbTemp[cbData] ;
|
|
pbTempLimit = & pbTemp[(cbData / sizeof(WCHAR))-1] ;
|
|
|
|
// Catch exceptions trying to build the list
|
|
NC_TRY
|
|
{
|
|
|
|
for ( ; pbTemp < pbTempLimit ; )
|
|
{
|
|
// Raid 237766
|
|
if (pbTemp && wcslen(pbTemp))
|
|
{
|
|
strList.insert(strList.end(), new tstring(pbTemp) ) ;
|
|
}
|
|
pbTemp += wcslen( pbTemp ) + 1 ;
|
|
}
|
|
}
|
|
NC_CATCH_BAD_ALLOC
|
|
{
|
|
err = ERROR_NOT_ENOUGH_MEMORY ;
|
|
}
|
|
|
|
}
|
|
while ( FALSE ) ;
|
|
|
|
delete [] pabData ;
|
|
|
|
TraceRegFunctionError(err);
|
|
|
|
return err ;
|
|
}
|
|
|
|
LONG CORegKey::QueryValue ( PCWSTR pchValueName, DWORD& dwResult )
|
|
{
|
|
DefineFunctionName("CORegKey::QueryValue(DWORD& dwResult)");
|
|
|
|
LONG err = 0;
|
|
|
|
DWORD dwData;
|
|
|
|
if (m_hKey && (S_OK == HrRegQueryDword(m_hKey, pchValueName, &dwData)))
|
|
{
|
|
dwResult = dwData;
|
|
}
|
|
else
|
|
{
|
|
err = ERROR_FILE_NOT_FOUND;
|
|
dwResult = -1;
|
|
}
|
|
|
|
TraceRegFunctionError(err);
|
|
|
|
return err ;
|
|
}
|
|
|
|
LONG CORegKey::QueryValue ( PCWSTR pchValueName, TByteArray& abResult )
|
|
{
|
|
DefineFunctionName("CORegKey::QueryValue(TByteArray& abResult)");
|
|
|
|
LONG err = 0 ;
|
|
|
|
DWORD dwType ;
|
|
DWORD cbData ;
|
|
BYTE * pabData = NULL ;
|
|
|
|
do
|
|
{
|
|
if ( err = PrepareValue( pchValueName, & dwType, & cbData, & pabData ) )
|
|
break ;
|
|
|
|
if ( dwType != REG_BINARY )
|
|
{
|
|
err = ERROR_INVALID_PARAMETER ;
|
|
break ;
|
|
}
|
|
|
|
// Catch exceptions trying to grow the result array
|
|
NC_TRY
|
|
{
|
|
abResult.reserve( cbData ) ;
|
|
}
|
|
NC_CATCH_BAD_ALLOC
|
|
{
|
|
err = ERROR_NOT_ENOUGH_MEMORY ;
|
|
}
|
|
|
|
|
|
if ( err )
|
|
break ;
|
|
|
|
// Move the data to the result array.
|
|
for ( DWORD i = 0 ; i < cbData ; i++ )
|
|
{
|
|
// abResult[i] = pabData[i] ;
|
|
abResult.push_back(pabData[i]) ;
|
|
}
|
|
}
|
|
while ( FALSE ) ;
|
|
|
|
delete [] pabData ;
|
|
|
|
TraceRegFunctionError(err);
|
|
|
|
return err ;
|
|
}
|
|
|
|
LONG CORegKey::QueryValue ( PCWSTR pchValueName, void* pvResult, DWORD cbSize )
|
|
{
|
|
DefineFunctionName("CORegKey::QueryValue(void* pvResult, DWORD cbSize)");
|
|
|
|
LONG err = 0 ;
|
|
|
|
DWORD dwType ;
|
|
DWORD cbData ;
|
|
BYTE * pabData = NULL ;
|
|
|
|
do
|
|
{
|
|
if ( err = PrepareValue( pchValueName, & dwType, & cbData, & pabData ) )
|
|
break ;
|
|
|
|
if ( dwType != REG_BINARY )
|
|
{
|
|
err = ERROR_INVALID_PARAMETER ;
|
|
break ;
|
|
}
|
|
|
|
if ( cbSize < cbData )
|
|
{
|
|
err = ERROR_MORE_DATA;
|
|
break;
|
|
}
|
|
|
|
::memcpy(pvResult, pabData, cbData);
|
|
}
|
|
while ( FALSE ) ;
|
|
|
|
delete [] pabData ;
|
|
|
|
TraceRegFunctionError(err);
|
|
|
|
return err ;
|
|
}
|
|
|
|
|
|
// Overloaded value setting members.
|
|
LONG CORegKey::SetValue ( PCWSTR pchValueName, tstring& strResult )
|
|
{
|
|
DefineFunctionName("CORegKey::SetValue(tstring& strResult)");
|
|
|
|
LONG err = 0;
|
|
|
|
err = ::RegSetValueEx( *this,
|
|
pchValueName,
|
|
0,
|
|
REG_SZ,
|
|
(const BYTE *) strResult.c_str(),
|
|
CbOfSzAndTerm (strResult.c_str())) ;
|
|
|
|
TraceRegFunctionError(err);
|
|
|
|
return err ;
|
|
}
|
|
|
|
// Overloaded value setting members.
|
|
LONG CORegKey::SetValue ( PCWSTR pchValueName, tstring& strResult ,
|
|
BOOL fRegExpand)
|
|
{
|
|
LONG err = 0;
|
|
DWORD dwType = fRegExpand ? REG_EXPAND_SZ : REG_SZ;
|
|
|
|
err = ::RegSetValueEx( *this,
|
|
pchValueName,
|
|
0,
|
|
dwType,
|
|
(const BYTE *) strResult.c_str(),
|
|
CbOfSzAndTerm (strResult.c_str()));
|
|
|
|
return err ;
|
|
}
|
|
|
|
LONG CORegKey::SetValue ( PCWSTR pchValueName, TStringList& strList )
|
|
{
|
|
DefineFunctionName("CORegKey::SetValue(TStringList& strList)");
|
|
|
|
|
|
LONG err = 0;
|
|
|
|
DWORD cbSize ;
|
|
BYTE * pbData = NULL ;
|
|
|
|
err = FlattenValue( strList, & cbSize, & pbData ) ;
|
|
|
|
if ( err == 0 )
|
|
{
|
|
err = ::RegSetValueEx( *this,
|
|
pchValueName,
|
|
0,
|
|
REG_MULTI_SZ,
|
|
pbData,
|
|
cbSize ) ;
|
|
}
|
|
|
|
delete pbData ;
|
|
|
|
TraceRegFunctionError(err);
|
|
|
|
return err ;
|
|
}
|
|
|
|
LONG CORegKey::SetValue ( PCWSTR pchValueName, DWORD& dwResult )
|
|
{
|
|
DefineFunctionName("CORegKey::SetValue(DWORD& dwResult)");
|
|
|
|
LONG err = 0;
|
|
|
|
err = ::RegSetValueEx( *this,
|
|
pchValueName,
|
|
0,
|
|
REG_DWORD,
|
|
(const BYTE *) & dwResult,
|
|
sizeof dwResult ) ;
|
|
|
|
TraceRegFunctionError(err);
|
|
|
|
return err ;
|
|
}
|
|
|
|
LONG CORegKey::SetValue ( PCWSTR pchValueName, TByteArray& abResult )
|
|
{
|
|
DefineFunctionName("CORegKey::SetValue(TByteArray& abResult)");
|
|
|
|
|
|
LONG err = 0;
|
|
|
|
DWORD cbSize ;
|
|
BYTE * pbData = NULL ;
|
|
|
|
err = FlattenValue( abResult, & cbSize, & pbData ) ;
|
|
|
|
if ( err == 0 )
|
|
{
|
|
err = ::RegSetValueEx( *this,
|
|
pchValueName,
|
|
0,
|
|
REG_BINARY,
|
|
pbData,
|
|
cbSize ) ;
|
|
}
|
|
|
|
delete pbData ;
|
|
|
|
TraceRegFunctionError(err);
|
|
|
|
return err ;
|
|
}
|
|
|
|
LONG CORegKey::SetValue ( PCWSTR pchValueName, void* pvResult, DWORD cbSize )
|
|
{
|
|
DefineFunctionName("CORegKey::SetValue(void* pvResult, DWORD cbSize)");
|
|
|
|
|
|
LONG err = 0;
|
|
|
|
err = ::RegSetValueEx( *this,
|
|
pchValueName,
|
|
0,
|
|
REG_BINARY,
|
|
(const BYTE *)pvResult,
|
|
cbSize ) ;
|
|
|
|
TraceRegFunctionError(err);
|
|
|
|
return err ;
|
|
}
|
|
|
|
|
|
LONG CORegKey::DeleteValue ( PCWSTR pchValueName )
|
|
{
|
|
DefineFunctionName("CORegKey::DeleteValue");
|
|
|
|
LONG err = ::RegDeleteValue(m_hKey, pchValueName);
|
|
|
|
TraceRegFunctionError(err);
|
|
|
|
return err;
|
|
}
|
|
|
|
|
|
LONG CORegKey::FlattenValue (TStringList & strList,
|
|
DWORD * pcbSize,
|
|
BYTE ** ppbData )
|
|
{
|
|
Assert(pcbSize);
|
|
Assert(ppbData);
|
|
DefineFunctionName("CORegKey::FlattenValue(TStringList)");
|
|
|
|
|
|
LONG err = ERROR_NOT_ENOUGH_MEMORY ;
|
|
|
|
TStringListIter pos ;
|
|
tstring* pstr ;
|
|
int cbTotal = 0 ;
|
|
|
|
*ppbData = NULL;
|
|
|
|
// Walk the list accumulating sizes
|
|
for ( pos = strList.begin() ;
|
|
pos != strList.end() && (pstr = (tstring *) *pos++); )
|
|
{
|
|
cbTotal += CbOfSzAndTerm (pstr->c_str());
|
|
}
|
|
|
|
// Allocate and fill a temporary buffer
|
|
if (*pcbSize = cbTotal)
|
|
{
|
|
BYTE * pbData = new BYTE[ *pcbSize ] ;
|
|
if(pbData)
|
|
{
|
|
// Populate the buffer with the strings.
|
|
for ( pos = strList.begin() ;
|
|
pos != strList.end() && (pstr = (tstring *) *pos++); )
|
|
{
|
|
int cb = CbOfSzAndTerm (pstr->c_str());
|
|
::memcpy( pbData, pstr->c_str(), cb ) ;
|
|
pbData += cb ;
|
|
}
|
|
err = NOERROR;
|
|
*ppbData = pbData;
|
|
}
|
|
}
|
|
|
|
TraceRegFunctionError(err);
|
|
|
|
return err ;
|
|
}
|
|
|
|
LONG CORegKey::FlattenValue (TByteArray & abData,
|
|
DWORD * pcbSize,
|
|
BYTE ** ppbData )
|
|
{
|
|
Assert(pcbSize);
|
|
Assert(ppbData);
|
|
|
|
DefineFunctionName("CORegKey::FlattenValue(TByteArray)");
|
|
|
|
LONG err = ERROR_NOT_ENOUGH_MEMORY ;
|
|
|
|
DWORD i ;
|
|
|
|
*ppbData = NULL;
|
|
|
|
// Allocate and fill a temporary buffer
|
|
if (*pcbSize = abData.size())
|
|
{
|
|
*ppbData = new BYTE[*pcbSize] ;
|
|
|
|
if(*ppbData)
|
|
{
|
|
for ( i = 0 ; i < *pcbSize ; i++ )
|
|
{
|
|
(*ppbData)[i] = abData[i] ;
|
|
}
|
|
}
|
|
|
|
err = NOERROR;
|
|
}
|
|
|
|
TraceRegFunctionError(err);
|
|
|
|
return err ;
|
|
}
|
|
|
|
|
|
LONG CORegKey::QueryKeyInfo ( CORegKEY_KEY_INFO * pRegKeyInfo )
|
|
{
|
|
DefineFunctionName("CORegKey::QueryKeyInfo");
|
|
|
|
LONG err = 0 ;
|
|
|
|
pRegKeyInfo->dwClassNameSize = sizeof pRegKeyInfo->chBuff - 1 ;
|
|
|
|
err = ::RegQueryInfoKeyW( *this,
|
|
pRegKeyInfo->chBuff,
|
|
& pRegKeyInfo->dwClassNameSize,
|
|
NULL,
|
|
& pRegKeyInfo->dwNumSubKeys,
|
|
& pRegKeyInfo->dwMaxSubKey,
|
|
& pRegKeyInfo->dwMaxClass,
|
|
& pRegKeyInfo->dwMaxValues,
|
|
& pRegKeyInfo->dwMaxValueName,
|
|
& pRegKeyInfo->dwMaxValueData,
|
|
& pRegKeyInfo->dwSecDesc,
|
|
& pRegKeyInfo->ftKey ) ;
|
|
|
|
TraceRegFunctionError(err);
|
|
|
|
return err ;
|
|
}
|
|
|
|
CORegKeyIter::CORegKeyIter ( CORegKey & regKey )
|
|
: m_rk_iter( regKey ),
|
|
m_p_buffer( NULL ),
|
|
m_cb_buffer( 0 )
|
|
{
|
|
DefineFunctionName("CORegKeyIter::CORegKeyIter");
|
|
|
|
LONG err = 0 ;
|
|
|
|
CORegKey::CORegKEY_KEY_INFO regKeyInfo ;
|
|
|
|
Reset() ;
|
|
|
|
err = regKey.QueryKeyInfo( & regKeyInfo ) ;
|
|
|
|
if ( err == 0 )
|
|
{
|
|
NC_TRY
|
|
{
|
|
m_cb_buffer = regKeyInfo.dwMaxSubKey + sizeof (DWORD) ;
|
|
m_p_buffer = new WCHAR [ m_cb_buffer ] ;
|
|
}
|
|
NC_CATCH_BAD_ALLOC
|
|
{
|
|
err = ERROR_NOT_ENOUGH_MEMORY ;
|
|
}
|
|
|
|
}
|
|
|
|
TraceRegFunctionError(err);
|
|
}
|
|
|
|
CORegKeyIter::~CORegKeyIter ()
|
|
{
|
|
delete [] m_p_buffer ;
|
|
}
|
|
|
|
|
|
LONG CORegKeyIter::Next ( tstring * pstrName )
|
|
{
|
|
DefineFunctionName("CORegKeyIter::Next");
|
|
|
|
LONG err = 0;
|
|
|
|
FILETIME ftDummy ;
|
|
DWORD dwNameSize = m_cb_buffer ;
|
|
|
|
err = ::RegEnumKeyEx( m_rk_iter,
|
|
m_dw_index,
|
|
m_p_buffer,
|
|
& dwNameSize,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
& ftDummy ) ;
|
|
if ( err == 0 )
|
|
{
|
|
m_dw_index++ ;
|
|
|
|
NC_TRY
|
|
{
|
|
*pstrName = m_p_buffer ;
|
|
}
|
|
NC_CATCH_BAD_ALLOC
|
|
{
|
|
err = ERROR_NOT_ENOUGH_MEMORY ;
|
|
}
|
|
|
|
}
|
|
|
|
TraceRegFunctionError(err);
|
|
|
|
return err ;
|
|
}
|
|
|
|
|
|
CORegValueIter::CORegValueIter ( CORegKey & regKey )
|
|
: m_rk_iter( regKey ),
|
|
m_p_buffer( NULL ),
|
|
m_cb_buffer( 0 )
|
|
{
|
|
DefineFunctionName("CORegValueIter::CORegValueIter");
|
|
|
|
LONG err = 0 ;
|
|
|
|
CORegKey::CORegKEY_KEY_INFO regKeyInfo ;
|
|
|
|
Reset() ;
|
|
|
|
err = regKey.QueryKeyInfo( & regKeyInfo ) ;
|
|
|
|
if ( err == 0 )
|
|
{
|
|
NC_TRY
|
|
{
|
|
m_cb_buffer = regKeyInfo.dwMaxValueName + sizeof (DWORD) ;
|
|
m_p_buffer = new WCHAR [ m_cb_buffer ] ;
|
|
}
|
|
NC_CATCH_BAD_ALLOC
|
|
{
|
|
err = ERROR_NOT_ENOUGH_MEMORY ;
|
|
}
|
|
|
|
}
|
|
|
|
TraceRegFunctionError(err);
|
|
}
|
|
|
|
CORegValueIter::~CORegValueIter ()
|
|
{
|
|
delete [] m_p_buffer ;
|
|
}
|
|
|
|
LONG CORegValueIter::Next ( tstring * pstrName, DWORD * pdwType )
|
|
{
|
|
DefineFunctionName("CORegValueIter::Next");
|
|
|
|
LONG err = 0 ;
|
|
|
|
DWORD dwNameLength = m_cb_buffer ;
|
|
|
|
err = ::RegEnumValue( m_rk_iter,
|
|
m_dw_index,
|
|
m_p_buffer,
|
|
& dwNameLength,
|
|
NULL,
|
|
pdwType,
|
|
NULL,
|
|
NULL ) ;
|
|
|
|
if ( err == 0 )
|
|
{
|
|
m_dw_index++ ;
|
|
|
|
NC_TRY
|
|
{
|
|
*pstrName = m_p_buffer ;
|
|
}
|
|
NC_CATCH_BAD_ALLOC
|
|
{
|
|
err = ERROR_NOT_ENOUGH_MEMORY ;
|
|
}
|
|
}
|
|
|
|
TraceRegFunctionError(err);
|
|
return err ;
|
|
}
|