Source code of Windows XP (NT5)
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.
 
 
 
 
 
 

580 lines
16 KiB

//////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 1999-2000 Microsoft Corporation
//
// Module Name:
// CRegistryKey.cpp
//
// Description:
// Contains the definition of the CRegistryKey class.
//
// Maintained By:
// Vij Vasu (Vvasu) 08-MAR-2000
//
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// Include Files
//////////////////////////////////////////////////////////////////////////////
// The precompiled header.
#include "pch.h"
//////////////////////////////////////////////////////////////////////////////
//++
//
// CRegistryKey::CRegistryKey()
//
// Description:
// Default constructor of the CRegistryKey class
//
// Arguments:
// None.
//
// Return Value:
// None.
//
// Exceptions Thrown:
// None.
//
//--
//////////////////////////////////////////////////////////////////////////////
CRegistryKey::CRegistryKey( void ) throw()
{
BCATraceScope( "" );
} //*** CRegistryKey::CRegistryKey()
//////////////////////////////////////////////////////////////////////////////
//++
//
// CRegistryKey::CRegistryKey()
//
// Description:
// Constructor of the CRegistryKey class. Opens the specified key.
//
// Arguments:
// hKeyParentIn
// Handle to the parent key.
//
// pszSubKeyNameIn
// Name of the subkey.
//
// samDesiredIn
// Access rights desired. Defaults to KEY_ALL_ACCESS
//
// Return Value:
// None.
//
// Exceptions Thrown:
// Any thrown by functions called.
//
//--
//////////////////////////////////////////////////////////////////////////////
CRegistryKey::CRegistryKey(
HKEY hKeyParentIn
, const WCHAR * pszSubKeyNameIn
, REGSAM samDesiredIn
)
{
BCATraceScope( "" );
OpenKey( hKeyParentIn, pszSubKeyNameIn, samDesiredIn );
} //*** CRegistryKey::CRegistryKey()
//////////////////////////////////////////////////////////////////////////////
//++
//
// CRegistryKey::~CRegistryKey()
//
// Description:
// Default destructor of the CRegistryKey class
//
// Arguments:
// None.
//
// Return Value:
// None.
//
// Exceptions Thrown:
// None.
//
//--
//////////////////////////////////////////////////////////////////////////////
CRegistryKey::~CRegistryKey( void ) throw()
{
BCATraceScope( "" );
} //*** CRegistryKey::~CRegistryKey()
//////////////////////////////////////////////////////////////////////////////
//++
//
// void
// CRegistryKey::OpenKey()
//
// Description:
// Opens the specified key.
//
// Arguments:
// hKeyParentIn
// Handle to the parent key.
//
// pszSubKeyNameIn
// Name of the subkey.
//
// samDesiredIn
// Access rights desired. Defaults to KEY_ALL_ACCESS
//
// Return Value:
// None.
//
// Exceptions Thrown:
// CRuntimeError
// If any of the APIs fail.
//
//--
//////////////////////////////////////////////////////////////////////////////
void
CRegistryKey::OpenKey(
HKEY hKeyParentIn
, const WCHAR * pszSubKeyNameIn
, REGSAM samDesiredIn
)
{
BCATraceScope3( "hKeyParentIn = %p, pszSubKeyNameIn = '%ws', samDesiredIn = %#x", hKeyParentIn, pszSubKeyNameIn == NULL ? L"<null>" : pszSubKeyNameIn, samDesiredIn );
HKEY hTempKey = NULL;
LONG lRetVal;
lRetVal = TW32( RegOpenKeyEx(
hKeyParentIn
, pszSubKeyNameIn
, 0
, samDesiredIn
, &hTempKey
) );
// Was the key opened properly?
if ( lRetVal != ERROR_SUCCESS )
{
BCATraceMsg2( "RegOpenKeyEx( '%ws' ) retured error %#08x. Throwing an exception.", pszSubKeyNameIn, lRetVal );
LogMsg( "CRegistryKey::OpenKey - RegOpenKeyEx( '%ws' ) retured error %#08x. Throwing an exception.", pszSubKeyNameIn, lRetVal );
THROW_RUNTIME_ERROR(
HRESULT_FROM_WIN32( lRetVal )
, IDS_ERROR_REGISTRY_OPEN
);
} // if: RegOpenKeyEx failed.
BCATraceMsg1( "Handle to key = %p", hTempKey );
// Store the opened key in the member variable.
m_shkKey.Assign( hTempKey );
} //*** CRegistryKey::OpenKey()
//////////////////////////////////////////////////////////////////////////////
//++
//
// void
// CRegistryKey::CreateKey()
//
// Description:
// Creates the specified key. If the key already exists, this functions
// opens the key.
//
// Arguments:
// hKeyParentIn
// Handle to the parent key.
//
// pszSubKeyNameIn
// Name of the subkey.
//
// samDesiredIn
// Access rights desired. Defaults to KEY_ALL_ACCESS
//
// Return Value:
// None.
//
// Exceptions Thrown:
// CRuntimeError
// If any of the APIs fail.
//
//--
//////////////////////////////////////////////////////////////////////////////
void
CRegistryKey::CreateKey(
HKEY hKeyParentIn
, const WCHAR * pszSubKeyNameIn
, REGSAM samDesiredIn
)
{
BCATraceScope3( "hKeyParentIn = %p, pszSubKeyNameIn = '%ws', samDesiredIn = %#x", hKeyParentIn, pszSubKeyNameIn == NULL ? L"<null>" : pszSubKeyNameIn, samDesiredIn );
if ( pszSubKeyNameIn == NULL )
{
BCATraceMsg( "Key = NULL. This is an error! Throwing exception." );
THROW_ASSERT( E_INVALIDARG, "The name of the subkey cannot be NULL." );
}
HKEY hTempKey = NULL;
LONG lRetVal;
lRetVal = TW32( RegCreateKeyEx(
hKeyParentIn
, pszSubKeyNameIn
, 0
, NULL
, REG_OPTION_NON_VOLATILE
, samDesiredIn
, NULL
, &hTempKey
, NULL
) );
// Was the key opened properly?
if ( lRetVal != ERROR_SUCCESS )
{
BCATraceMsg2( "RegCreateKeyEx( '%ws' ) retured error %#08x. Throwing an exception.", pszSubKeyNameIn, lRetVal );
LogMsg( "CRegistryKey::CreateKey - RegCreateKeyEx( '%ws' ) retured error %#08x.", pszSubKeyNameIn, lRetVal );
THROW_RUNTIME_ERROR(
HRESULT_FROM_WIN32( lRetVal )
, IDS_ERROR_REGISTRY_CREATE
);
} // if: RegCreateKeyEx failed.
BCATraceMsg1( "Handle to key = %p", hTempKey );
// Store the opened key in the member variable.
m_shkKey.Assign( hTempKey );
} //*** CRegistryKey::CreateKey()
//////////////////////////////////////////////////////////////////////////////
//++
//
// void
// CRegistryKey::QueryValue()
//
// Description:
// Reads a value under this key. The memory for this value is allocated
// by this function. The caller is responsible for freeing this memory.
//
// Arguments:
// pszValueNameIn
// Name of the value to read.
//
// ppbDataOut
// Pointer to the pointer to the data. Cannot be NULL.
//
// pdwDataSizeInBytesOut
// Number of bytes allocated in the data buffer. Cannot be NULL.
//
// pdwTypeOut
// Pointer to the type of the value.
//
// Return Value:
// None.
//
// Exceptions Thrown:
// CRuntimeError
// If any of the APIs fail.
//
// CAssert
// If the parameters are incorrect.
//
//--
//////////////////////////////////////////////////////////////////////////////
void
CRegistryKey::QueryValue(
const WCHAR * pszValueNameIn
, LPBYTE * ppbDataOut
, LPDWORD pdwDataSizeBytesOut
, LPDWORD pdwTypeOut
) const
{
BCATraceScope1( "pszValueNameIn = '%ws'", pszValueNameIn == NULL ? L"<null>" : pszValueNameIn );
LONG lRetVal = ERROR_SUCCESS;
DWORD cbBufferSize = 0;
DWORD dwType = REG_SZ;
// Check parameters
if ( ( pdwDataSizeBytesOut == NULL )
|| ( ppbDataOut == NULL )
)
{
BCATraceMsg( "One of the required input pointers is NULL. Throwing exception." );
THROW_ASSERT(
E_INVALIDARG
, "CRegistryKey::QueryValue() => Required input pointer in NULL"
);
} // if: parameters are invalid.
// Initialize outputs.
*ppbDataOut = NULL;
*pdwDataSizeBytesOut = 0;
// Get the required size of the buffer.
lRetVal = TW32( RegQueryValueEx(
m_shkKey.HHandle() // handle to key to query
, pszValueNameIn // address of name of value to query
, 0 // reserved
, NULL // address of buffer for value type
, NULL // address of data buffer
, &cbBufferSize // address of data buffer size
) );
if ( lRetVal != ERROR_SUCCESS )
{
BCATraceMsg2( "RegQueryValueEx( '%ws' ) retured error %#08x. Throwing an exception.", pszValueNameIn, lRetVal );
LogMsg( "CRegistryKey::QueryValue - RegQueryValueEx( '%ws' ) retured error %#08x.", pszValueNameIn, lRetVal );
THROW_RUNTIME_ERROR(
HRESULT_FROM_WIN32( lRetVal )
, IDS_ERROR_REGISTRY_QUERY
);
}
SmartByteArray sbaBuffer( new BYTE[ cbBufferSize ] );
if ( sbaBuffer.FIsEmpty() )
{
BCATraceMsg1( "Could not allocate %d bytes of memory. Throwing an exception.", cbBufferSize );
LogMsg( "CRegistryKey::QueryValue - Could not allocate %d bytes of memory.", lRetVal );
THROW_RUNTIME_ERROR(
THR( E_OUTOFMEMORY )
, IDS_ERROR_REGISTRY_QUERY
);
}
// Read the value.
lRetVal = TW32( RegQueryValueEx(
m_shkKey.HHandle() // handle to key to query
, pszValueNameIn // address of name of value to query
, 0 // reserved
, &dwType // address of buffer for value type
, sbaBuffer.PMem() // address of data buffer
, &cbBufferSize // address of data buffer size
) );
// Was the key read properly?
if ( lRetVal != ERROR_SUCCESS )
{
BCATraceMsg2( "RegQueryValueEx( '%ws' ) retured error %#08x. Throwing an exception.", pszValueNameIn, lRetVal );
LogMsg( "CRegistryKey::QueryValue - RegQueryValueEx( '%ws' ) retured error %#08x.", pszValueNameIn, lRetVal );
THROW_RUNTIME_ERROR(
HRESULT_FROM_WIN32( lRetVal )
, IDS_ERROR_REGISTRY_QUERY
);
} // if: RegQueryValueEx failed.
*ppbDataOut = sbaBuffer.PRelease();
*pdwDataSizeBytesOut = cbBufferSize;
if ( pdwTypeOut != NULL )
{
*pdwTypeOut = dwType;
}
} //*** CRegistryKey::QueryValue()
//////////////////////////////////////////////////////////////////////////////
//++
//
// void
// CRegistryKey::SetValue()
//
// Description:
// Writes a value under this key.
//
// Arguments:
// pszValueNameIn
// Name of the value to be set.
//
// cpbDataIn
// Pointer to the pointer to the data buffer.
//
// dwDataSizeInBytesIn
// Number of bytes in the data buffer.
//
// pdwTypeIn
// Type of the value.
//
// Return Value:
// None.
//
// Exceptions Thrown:
// CRuntimeError
// If any of the APIs fail.
//
//--
//////////////////////////////////////////////////////////////////////////////
void
CRegistryKey::SetValue(
const WCHAR * pszValueNameIn
, DWORD dwTypeIn
, const BYTE * cpbDataIn
, DWORD dwDataSizeBytesIn
) const
{
BCATraceScope5(
"HKEY = %p, pszValueNameIn = '%s', dwTypeIn = %d, cpbDataIn = %p, dwDataSizeBytesIn = %d."
, m_shkKey.HHandle()
, pszValueNameIn
, dwTypeIn
, cpbDataIn
, dwDataSizeBytesIn
);
DWORD dwRetVal = TW32( RegSetValueEx(
m_shkKey.HHandle()
, pszValueNameIn
, 0
, dwTypeIn
, cpbDataIn
, dwDataSizeBytesIn
) );
if ( dwRetVal != ERROR_SUCCESS )
{
BCATraceMsg2( "RegSetValueEx( '%s' ) retured error %#x. Throwing an exception.", pszValueNameIn, dwRetVal );
LogMsg( "CRegistryKey::SetValue - RegSetValueEx( '%s' ) retured error %#x.", pszValueNameIn, dwRetVal );
THROW_RUNTIME_ERROR(
HRESULT_FROM_WIN32( dwRetVal )
, IDS_ERROR_REGISTRY_SET
);
} // if: RegSetValueEx failed.
} //*** CRegistryKey::SetValue()
//////////////////////////////////////////////////////////////////////////////
//++
//
// void
// CRegistryKey::RenameKey()
//
// Description:
// Rename this key.
//
// Arguments:
// pszNewNameIn
// The new name for this key.
//
// Return Value:
// None.
//
// Exceptions Thrown:
// CRuntimeError
// If any of the APIs fail.
//
// IMPORTANT NOTE:
// This function calls the NtRenameKey API with the handle returned by
// RegOpenKeyEx. This will work as long as we are not dealing with a
// remote registry key.
//
//--
//////////////////////////////////////////////////////////////////////////////
void
CRegistryKey::RenameKey(
const WCHAR * pszNewNameIn
)
{
BCATraceScope2(
"HKEY = %p, pszNewNameIn = '%s'."
, m_shkKey.HHandle()
, pszNewNameIn
);
UNICODE_STRING ustrNewName;
DWORD dwRetVal = ERROR_SUCCESS;
RtlInitUnicodeString( &ustrNewName, pszNewNameIn );
// Begin_Replace00
//
// BUGBUG: Vij Vasu (Vvasu) 10-APR-2000
// Dynamically linking to NtDll.dll to allow testing on Win2K
// Replace the section below ( Begin_Replace00 to End-Replace00 ) with
// the single marked statment ( Begin_Replacement00 to End_Replacement00 ).
//
{
typedef CSmartResource<
CHandleTrait<
HMODULE
, BOOL
, FreeLibrary
, reinterpret_cast< HMODULE >( NULL )
>
> SmartModuleHandle;
SmartModuleHandle smhNtDll( LoadLibrary( L"NtDll.dll" ) );
if ( smhNtDll.FIsInvalid() )
{
dwRetVal = GetLastError();
BCATraceMsg1( "LoadLibrary() retured error %#08x. Throwing an exception.", dwRetVal );
THROW_RUNTIME_ERROR(
dwRetVal // NTSTATUS codes are compatible with HRESULTS
, IDS_ERROR_REGISTRY_RENAME
);
} // if: LoadLibrary failed.
FARPROC pNtRenameKey = GetProcAddress( smhNtDll.HHandle(), "NtRenameKey" );
if ( pNtRenameKey == NULL )
{
dwRetVal = GetLastError();
BCATraceMsg1( "GetProcAddress() retured error %#08x. Throwing an exception.", dwRetVal );
THROW_RUNTIME_ERROR(
dwRetVal // NTSTATUS codes are compatible with HRESULTS
, IDS_ERROR_REGISTRY_RENAME
);
} // if: GetProcAddress() failed
dwRetVal = ( reinterpret_cast< NTSTATUS (*)( HANDLE, PUNICODE_STRING ) >( pNtRenameKey ) )(
m_shkKey.HHandle()
, &ustrNewName
);
}
// End_Replace00
/* Begin_Replacement00 - delete this line
dwRetVal = NtRenameKey(
m_shkKey.HHandle()
, &ustrNewName
);
End_Replacement00 - delete this line */
if ( NT_ERROR( dwRetVal ) )
{
BCATraceMsg2( "NtRenameKey( '%ws' ) retured error %#08x. Throwing an exception.", pszNewNameIn, dwRetVal );
LogMsg( "CRegistryKey::RenameKey - NtRenameKey( '%ws' ) retured error %#08x.", pszNewNameIn, dwRetVal );
THROW_RUNTIME_ERROR(
dwRetVal // NTSTATUS codes are compatible with HRESULTS
, IDS_ERROR_REGISTRY_RENAME
);
} // if: RegRenameKeyEx failed.
} //*** CRegistryKey::RenameKey()