Leaked source code of windows server 2003
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.
 
 
 
 
 
 

534 lines
15 KiB

/*++
Copyright (C) Microsoft Corporation, 1997 - 1998
All rights reserved.
Module Name:
persist.cxx
Abstract:
Persistent store class.
Author:
Steve Kiraly (SteveKi) 05/12/97
Revision History:
--*/
#include "precomp.hxx"
#pragma hdrstop
#include "persist.hxx"
/********************************************************************
Persistant store class.
********************************************************************/
TPersist::
TPersist(
IN LPCTSTR pszSection,
IN UINT ioFlags,
IN HKEY hOpenedKey
) : strSection_( pszSection ),
hKey_( NULL ),
dwStatus_( ERROR_SUCCESS )
{
SPLASSERT( pszSection );
SPLASSERT( hOpenedKey );
DWORD dwDisposition = 0;
UINT uAccessIndex = 0;
static DWORD adwAccess [] = { 0, KEY_READ, KEY_WRITE, KEY_ALL_ACCESS };
uAccessIndex = ioFlags & ( kRead | kWrite );
if( uAccessIndex )
{
if( ioFlags & kCreate )
{
dwStatus_ = RegCreateKeyEx( hOpenedKey,
strSection_,
0,
NULL,
0,
adwAccess[ uAccessIndex ],
NULL,
&hKey_,
&dwDisposition );
}
else if( ioFlags & kOpen )
{
dwStatus_ = RegOpenKeyEx( hOpenedKey,
strSection_,
0,
adwAccess[ uAccessIndex ],
&hKey_ );
}
}
}
TPersist::
~TPersist(
VOID
)
{
if( hKey_ )
{
RegCloseKey( hKey_ );
}
}
BOOL
TPersist::
bValid(
VOID
) const
{
//
// A valid hKey and a valid section name is the class valid check.
//
return hKey_ != NULL && strSection_.bValid();
}
DWORD
TPersist::
dwLastError(
VOID
) const
{
return dwStatus_;
}
BOOL
TPersist::
bRead(
IN LPCTSTR pValueName,
IN OUT DWORD &dwValue
)
{
SPLASSERT( bValid() );
SPLASSERT( pValueName );
DWORD dwType = REG_DWORD;
DWORD dwSize = sizeof( dwValue );
dwStatus_ = RegQueryValueEx( hKey_,
pValueName,
NULL,
&dwType,
reinterpret_cast<LPBYTE>( &dwValue ),
&dwSize );
return dwStatus_ == ERROR_SUCCESS && dwType == REG_DWORD;
}
BOOL
TPersist::
bRead(
IN LPCTSTR pValueName,
IN OUT BOOL &bValue
)
{
SPLASSERT( bValid() );
SPLASSERT( pValueName );
DWORD dwType = REG_DWORD;
DWORD dwSize = sizeof( bValue );
dwStatus_ = RegQueryValueEx( hKey_,
pValueName,
NULL,
&dwType,
reinterpret_cast<LPBYTE>( &bValue ),
&dwSize );
return dwStatus_ == ERROR_SUCCESS && dwType == REG_DWORD;
}
BOOL
TPersist::
bRead(
IN LPCTSTR pValueName,
IN OUT TString &strValue
)
{
SPLASSERT( bValid() );
SPLASSERT( pValueName );
TCHAR szBuffer[kHint];
DWORD dwType = REG_SZ;
BOOL bStatus = FALSE;
DWORD cbSize = sizeof( szBuffer );
dwStatus_ = RegQueryValueEx( hKey_,
pValueName,
NULL,
&dwType,
reinterpret_cast<LPBYTE>( szBuffer ),
&cbSize );
if( dwStatus_ == ERROR_MORE_DATA && dwType == REG_SZ && cbSize )
{
//
// cbSize is the requested size of the buffer in bytes.
// allocate two more characters - one to make sure the
// cbSize / sizeof(TCHAR) is rounded up properly and one
// for a zero terminator to cover the case where the
// data is not properly zero terminated when written.
//
DWORD cchSize = cbSize / sizeof(TCHAR) + 2;
LPTSTR pszBuff = new TCHAR[ cchSize ];
if( pszBuff )
{
cbSize = cchSize * sizeof(TCHAR);
dwStatus_ = RegQueryValueEx( hKey_,
pValueName,
NULL,
&dwType,
reinterpret_cast<LPBYTE>( pszBuff ),
&cbSize );
}
else
{
dwStatus_ = ERROR_NOT_ENOUGH_MEMORY;
}
if( dwStatus_ == ERROR_SUCCESS )
{
//
// RegQueryValueEx may not zero terminate the buffer if the
// data in the registry is not zero terminated. Make sure it
// is properly zero terminated.
//
pszBuff[cchSize-1] = 0;
bStatus = strValue.bUpdate( pszBuff );
}
delete [] pszBuff;
}
else
{
if( dwStatus_ == ERROR_SUCCESS && dwType == REG_SZ )
{
//
// RegQueryValueEx may not zero terminate the buffer if the
// data in the registry is not zero terminated. Make sure it
// is properly zero terminated.
//
szBuffer[ARRAYSIZE(szBuffer)-1] = 0;
bStatus = strValue.bUpdate( szBuffer );
}
}
return bStatus;
}
BOOL
TPersist::
bRead(
IN LPCTSTR pValueName,
IN OUT PVOID pValue,
IN DWORD cbSize,
IN LPDWORD pcbNeeded OPTIONAL
)
{
SPLASSERT( bValid() );
SPLASSERT( pValueName );
SPLASSERT( pValue );
DWORD dwType = REG_BINARY;
BOOL bStatus = FALSE;
DWORD dwSize = cbSize;
dwStatus_ = RegQueryValueEx( hKey_,
pValueName,
NULL,
&dwType,
reinterpret_cast<LPBYTE>( pValue ),
&dwSize );
if( dwStatus_ == ERROR_MORE_DATA && pcbNeeded )
{
*pcbNeeded = dwSize;
}
return dwStatus_ == ERROR_SUCCESS && dwType == REG_BINARY && dwSize == cbSize;
}
BOOL
TPersist::
bWrite(
IN LPCTSTR pValueName,
IN const DWORD dwValue
)
{
SPLASSERT( bValid() );
SPLASSERT( pValueName );
dwStatus_ = RegSetValueEx( hKey_,
pValueName,
0,
REG_DWORD,
reinterpret_cast<const BYTE *>( &dwValue ),
sizeof( dwValue ) );
return dwStatus_ == ERROR_SUCCESS;
}
BOOL
TPersist::
bWrite(
IN LPCTSTR pValueName,
IN LPCTSTR pszValue
)
{
SPLASSERT( bValid() );
SPLASSERT( pValueName );
dwStatus_ = RegSetValueEx( hKey_,
pValueName,
0,
REG_SZ,
reinterpret_cast<const BYTE *>( pszValue ),
_tcslen( pszValue ) * sizeof( TCHAR ) + sizeof( TCHAR ) );
return dwStatus_ == ERROR_SUCCESS;
}
BOOL
TPersist::
bWrite(
IN LPCTSTR pValueName,
IN const PVOID pValue,
IN DWORD cbSize
)
{
SPLASSERT( bValid() );
SPLASSERT( pValueName );
SPLASSERT( pValue );
dwStatus_ = RegSetValueEx( hKey_,
pValueName,
0,
REG_BINARY,
reinterpret_cast<const BYTE *>( pValue ),
cbSize );
return dwStatus_ == ERROR_SUCCESS;
}
BOOL
TPersist::
bRemove(
IN LPCTSTR pValueName
)
{
SPLASSERT( bValid() );
SPLASSERT( pValueName );
dwStatus_ = RegDeleteValue( hKey_, pValueName );
return dwStatus_ == ERROR_SUCCESS;
}
BOOL
TPersist::
bRemoveKey(
IN LPCTSTR pKeyName
)
{
SPLASSERT( bValid() );
SPLASSERT( pKeyName );
dwStatus_ = dwRecursiveRegDeleteKey( hKey_, pKeyName );
return dwStatus_ == ERROR_SUCCESS;
}
DWORD
TPersist::
dwRecursiveRegDeleteKey(
IN HKEY hKey,
IN LPCTSTR pszSubkey
) const
{
HKEY hSubkey = NULL;
DWORD dwStatus = RegOpenKeyEx( hKey,
pszSubkey,
0,
KEY_ALL_ACCESS,
&hSubkey );
while ( dwStatus == ERROR_SUCCESS )
{
TCHAR szSubkey[ MAX_PATH ];
DWORD cbSubkeySize = COUNTOF( szSubkey );
dwStatus = RegEnumKeyEx( hSubkey,
0,
szSubkey,
&cbSubkeySize,
0,
0,
0,
0 );
if( dwStatus == ERROR_NO_MORE_ITEMS )
break;
if( dwStatus != ERROR_SUCCESS )
return dwStatus;
dwStatus = dwRecursiveRegDeleteKey( hSubkey, szSubkey );
}
if( hSubkey )
{
RegCloseKey( hSubkey );
}
dwStatus = RegDeleteKey( hKey, pszSubkey );
return dwStatus;
}
#if DBG
VOID
TestPersistClass(
VOID
)
{
TStatusB bStatus;
TString strValue;
DWORD dwValue = 0xDEADBEEF;
LPCTSTR pszValue = TEXT( "TestValueData" );
DWORD cbNeeded = 0;
TCHAR szValue[MAX_PATH];
for( UINT i = 0; i < COUNTOF( szValue )-1; i++ )
szValue[i] = TEXT('A');
szValue[i] = 0;
{
TPersist Persist( TEXT( "Printers\\Settings\\Test" ), TPersist::kCreate|TPersist::kWrite );
if( VALID_OBJ( Persist ) )
{
bStatus DBGCHK = Persist.bWrite( TEXT("Test Value dword"), dwValue );
bStatus DBGCHK = Persist.bWrite( TEXT("Test Value string"), TEXT("Test") );
bStatus DBGCHK = Persist.bWrite( TEXT("Test Value binary"), szValue, sizeof( szValue ) );
}
}
{
TPersist Persist( TEXT( "Printers\\Settings\\Test" ), TPersist::kOpen|TPersist::kRead );
if( VALID_OBJ( Persist ) )
{
bStatus DBGCHK = Persist.bRead( TEXT("Test Value dword"), dwValue );
DBGMSG( DBG_TRACE, ("Test value dword %x\n", dwValue ) );
bStatus DBGCHK = Persist.bRead( TEXT("Test Value string"), strValue );
DBGMSG( DBG_TRACE, ("Test value string " TSTR "\n", (LPCTSTR)strValue ) );
DBGMSG( DBG_TRACE, ("1Test value binary\n" ) );
bStatus DBGCHK = Persist.bRead( TEXT("Test Value binary"), szValue, sizeof( szValue ) - 1 );
if( bStatus )
{
DBGMSG( DBG_TRACE, ("1Test value binary succeeded\n" ) );
DBGMSG( DBG_TRACE, ("-"TSTR"-\n", szValue) );
}
else
{
DBGMSG( DBG_TRACE, ("1Test value binary failed with %d\n", Persist.dwLastError() ) );
}
DBGMSG( DBG_TRACE, ("2Test value binary\n" ) );
bStatus DBGCHK = Persist.bRead( TEXT("Test Value binary"), szValue, sizeof( szValue ) );
if( bStatus )
{
DBGMSG( DBG_TRACE, ("2Test value binary succeeded\n" ) );
DBGMSG( DBG_TRACE, ("-"TSTR"-\n", szValue) );
}
else
{
DBGMSG( DBG_TRACE, ("2Test value binary failed with %d\n", Persist.dwLastError() ) );
}
DBGMSG( DBG_TRACE, ("3Test value binary\n" ) );
bStatus DBGCHK = Persist.bRead( TEXT("Test Value binary"), szValue, sizeof( szValue )-8, &cbNeeded );
if( bStatus )
{
DBGMSG( DBG_TRACE, ("3Test value binary succeeded\n" ) );
DBGMSG( DBG_TRACE, ("-"TSTR"-\n", szValue) );
}
else
{
DBGMSG( DBG_TRACE, ("3Test value binary cbNeeded %d LastError %d\n", cbNeeded, Persist.dwLastError() ) );
}
}
}
{
TPersist Persist( TEXT( "Printers\\Settings\\Test" ), TPersist::kOpen|TPersist::kRead|TPersist::kWrite );
if( VALID_OBJ( Persist ) )
{
bStatus DBGCHK = Persist.bRemove( TEXT("dead") );
if( !bStatus )
DBGMSG( DBG_TRACE, ("Remove of " TSTR " failed LastError %d\n", TEXT("dead"), Persist.dwLastError() ) );
bStatus DBGCHK = Persist.bRemove( TEXT("Test Value dwordx") );
if( !bStatus )
DBGMSG( DBG_TRACE, ("Remove of " TSTR " failed LastError %d\n", TEXT("Test Value dwordx"), Persist.dwLastError() ) );
bStatus DBGCHK = Persist.bRemove( TEXT("Test Value dword") );
if( !bStatus )
DBGMSG( DBG_TRACE, ("Remove of " TSTR " failed LastError %d\n", TEXT("Test Value dword"), Persist.dwLastError() ) );
bStatus DBGCHK = Persist.bRemove( TEXT("Test Value string") );
if( !bStatus )
DBGMSG( DBG_TRACE, ("Remove of " TSTR " failed LastError %d\n", TEXT("Test Value string"), Persist.dwLastError() ) );
bStatus DBGCHK = Persist.bRemove( TEXT("Test Value binary") );
if( !bStatus )
DBGMSG( DBG_TRACE, ("Remove of " TSTR " failed LastError %d\n", TEXT("Test Value binary"), Persist.dwLastError() ) );
bStatus DBGCHK = Persist.bRemoveKey( TEXT("Test") );
if( !bStatus )
DBGMSG( DBG_TRACE, ("Remove key of " TSTR " failed LastError %d\n", TEXT("Test"), Persist.dwLastError() ) );
}
}
{
TPersist Persist( TEXT( "Printers\\Settings" ), TPersist::kOpen|TPersist::kRead|TPersist::kWrite );
if( VALID_OBJ( Persist ) )
{
bStatus DBGCHK = Persist.bRemoveKey( TEXT("Test") );
if( !bStatus )
DBGMSG( DBG_TRACE, ("Remove key of " TSTR " failed LastError %d\n", TEXT("Test"), Persist.dwLastError() ) );
}
}
}
#endif