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.
 
 
 
 
 
 

889 lines
15 KiB

/*++
Copyright (c) 1994 Microsoft Corporation
Module Name:
reg.cxx
Abstract:
Contains code that implements REGISTRY_OBJ class defined in reg.hxx.
Author:
Madan Appiah (madana) 19-Dec-1994
Environment:
User Mode - Win32
Revision History:
--*/
#include <svcloc.hxx>
MEMORY *CacheHeap = NULL;
INLINE
DWORD
REGISTRY_OBJ::GetValueSizeAndType(
LPWSTR ValueName,
LPDWORD ValueSize,
LPDWORD ValueType
)
/*++
Routine Description:
This function returns the size and type of a value of this key.
Arguments:
ValueName : name of the value whose size and type returned.
ValueSize : pointer to a location where the value size is returned.
ValueType : pointer to a location where the value type is returned.
Return Value:
Windows Error Code.
--*/
{
DWORD Error;
Error = RegQueryValueExW(
_RegHandle,
ValueName,
0,
ValueType,
NULL,
ValueSize );
return( Error );
}
REGISTRY_OBJ::REGISTRY_OBJ(
HKEY Handle,
DWORD Error
)
/*++
Routine Description:
This function is a inline function that initialize the registry
object with given handle and status.
Arguments:
Handle : registry object handle value.
Error : registry object status value.
Return Value:
None.
--*/
{
_RegHandle = Handle;
_Status = Error;
_Index = 0;
_ValIndex = 0;
return;
};
REGISTRY_OBJ::REGISTRY_OBJ(
HKEY ParentHandle,
LPWSTR KeyName
)
/*++
Routine Description:
Initializes the registry object from its parent's registry key
handle and this object's keyname.
Arguments:
ParentHandle : registry handle of the parent key.
Keyname : key name of the new registry object being created.
Return Value:
None.
--*/
{
_Index = 0;
_ValIndex = 0;
_Status = RegOpenKeyExW(
ParentHandle,
KeyName,
0,
DEFAULT_KEY_ACCESS,
&_RegHandle );
if( _Status != ERROR_SUCCESS ) {
_RegHandle = NULL;
}
return;
}
REGISTRY_OBJ::REGISTRY_OBJ(
REGISTRY_OBJ *ParentObj,
LPWSTR KeyName
)
/*++
Routine Description:
Initializes the registry object from its parent's registry object
and this object's keyname.
Arguments:
ParentObj : registry object of the parent.
Keyname : key name of the new registry object being created.
Return Value:
None.
--*/
{
_Index = 0;
_ValIndex = 0;
_Status = RegOpenKeyExW(
ParentObj->_RegHandle,
KeyName,
0,
DEFAULT_KEY_ACCESS,
&_RegHandle );
if( _Status != ERROR_SUCCESS ) {
_RegHandle = NULL;
}
return;
}
DWORD
REGISTRY_OBJ::Create(
LPWSTR ChildName
)
/*++
Routine Description:
Creates a new subkey under this key.
Arguments:
ChildName : name of the subkey being created.
Return Value:
Windows Error Code.
--*/
{
HKEY ChildHandle;
DWORD KeyDisposition;
_Status = RegCreateKeyExW(
_RegHandle,
ChildName,
0,
DEFAULT_CLASS,
REG_OPTION_NON_VOLATILE,
DEFAULT_KEY_ACCESS,
NULL,
&ChildHandle,
&KeyDisposition );
if( _Status != ERROR_SUCCESS ) {
return( _Status );
}
if( KeyDisposition == REG_CREATED_NEW_KEY ) {
TcpsvcsDbgPrint(( DEBUG_REGISTRY,
"Registry key (%ws) is created.\n", ChildName ));
}
//
// close the child handle before return.
//
RegCloseKey( ChildHandle );
return( ERROR_SUCCESS );
}
DWORD
REGISTRY_OBJ::Create(
LPWSTR ChildName,
REGISTRY_OBJ **ChildObj
)
/*++
Routine Description:
Creates a new subney and a new subney registry object.
Arguments:
ChildName : name of the subkey being created.
Return Value:
Windows Error Code.
--*/
{
DWORD Error;
HKEY ChildHandle;
DWORD KeyDisposition;
Error = RegCreateKeyExW(
_RegHandle,
ChildName,
0,
DEFAULT_CLASS,
REG_OPTION_NON_VOLATILE,
DEFAULT_KEY_ACCESS,
NULL,
&ChildHandle,
&KeyDisposition );
if( Error != ERROR_SUCCESS ) {
*ChildObj = new REGISTRY_OBJ( NULL, Error );
}
else {
if( KeyDisposition == REG_CREATED_NEW_KEY ) {
TcpsvcsDbgPrint(( DEBUG_REGISTRY,
"Registry key (%ws) is created.\n", ChildName ));
}
*ChildObj = new REGISTRY_OBJ( ChildHandle, (DWORD)ERROR_SUCCESS );
}
return( Error );
}
DWORD
REGISTRY_OBJ::Create(
LPWSTR ChildName,
REGISTRY_OBJ **ChildObj,
DWORD *KeyDisposition
)
/*++
Routine Description:
Creates a new subney and a new subney registry object.
Arguments:
ChildName : name of the subkey being created.
ChildObj : pointer to a location where the child registry object
pointer is returned.
KeyDisposition : pointer to a location where the child KeyDisposition
value is returned.
Return Value:
Windows Error Code.
--*/
{
DWORD Error;
HKEY ChildHandle;
Error = RegCreateKeyExW(
_RegHandle,
ChildName,
0,
DEFAULT_CLASS,
REG_OPTION_NON_VOLATILE,
DEFAULT_KEY_ACCESS,
NULL,
&ChildHandle,
KeyDisposition );
if( Error != ERROR_SUCCESS ) {
*ChildObj = new REGISTRY_OBJ( NULL, Error );
}
else {
if( *KeyDisposition == REG_CREATED_NEW_KEY ) {
TcpsvcsDbgPrint(( DEBUG_REGISTRY,
"Registry key (%ws) is created.\n", ChildName ));
}
*ChildObj = new REGISTRY_OBJ( ChildHandle, (DWORD)ERROR_SUCCESS );
}
return( Error );
}
DWORD
REGISTRY_OBJ::GetValue(
LPWSTR ValueName,
DWORD *Data
)
/*++
Routine Description:
Gets a REG_DWORD value.
Arguments:
ValueName : name of the value being retrived.
Return Value:
Windows Error Code.
--*/
{
DWORD Error;
DWORD ValueType;
DWORD ValueSize = sizeof(DWORD);
Error = RegQueryValueExW(
_RegHandle,
ValueName,
0,
&ValueType,
(LPBYTE)Data,
&ValueSize );
TcpsvcsDbgAssert( ValueSize == sizeof( DWORD ) );
TcpsvcsDbgAssert( ValueType == REG_DWORD );
return( Error );
}
DWORD
REGISTRY_OBJ::GetValue(
LPWSTR ValueName,
LPWSTR *Data,
DWORD *NumStrings
)
/*++
Routine Description:
Gets a REG_SZ or REG_EXPAND_SZ or REG_MULTI_SZ value.
Arguments:
ValueName : name of the value being retrived.
Return Value:
Windows Error Code.
--*/
{
DWORD Error;
DWORD ValueType;
DWORD ValueSize;
LPBYTE StringData = NULL;
Error = GetValueSizeAndType( ValueName, &ValueSize, &ValueType );
if( Error != ERROR_SUCCESS ) {
return( Error );
}
TcpsvcsDbgAssert(
(ValueType == REG_SZ) ||
(ValueType == REG_EXPAND_SZ) ||
(ValueType == REG_MULTI_SZ) );
StringData = (LPBYTE)CacheHeap->Alloc( ValueSize );
if( StringData == NULL ) {
return( ERROR_NOT_ENOUGH_MEMORY );
}
Error = RegQueryValueExW(
_RegHandle,
ValueName,
0,
&ValueType,
StringData,
&ValueSize );
if( Error != ERROR_SUCCESS ) {
CacheHeap->Free( StringData );
return( Error );
}
*Data = (LPWSTR)StringData;
if( (ValueType == REG_SZ) || (ValueType == REG_EXPAND_SZ) ) {
*NumStrings = 1;
}
else {
DWORD Strings = 0;
LPWSTR StrPtr = (LPWSTR)StringData;
DWORD Len;
while( (Len = wcslen(StrPtr)) != 0 ) {
Strings++;
StrPtr = StrPtr + Len + 1;
}
*NumStrings = Strings;
}
return( ERROR_SUCCESS );
}
DWORD
REGISTRY_OBJ::GetValue(
LPWSTR ValueName,
LPBYTE *Data,
DWORD *DataLen
)
/*++
Routine Description:
Gets a REG_BINARY value.
Arguments:
ValueName : name of the value being retrived.
Return Value:
Windows Error Code.
--*/
{
DWORD Error;
DWORD ValueType;
DWORD ValueSize;
LPBYTE BinaryData = NULL;
Error = GetValueSizeAndType( ValueName, &ValueSize, &ValueType );
if( Error != ERROR_SUCCESS ) {
return( Error );
}
TcpsvcsDbgAssert( ValueType == REG_BINARY );
BinaryData = (LPBYTE)CacheHeap->Alloc( ValueSize );
if( BinaryData == NULL ) {
return( ERROR_NOT_ENOUGH_MEMORY );
}
Error = RegQueryValueExW(
_RegHandle,
ValueName,
0,
&ValueType,
BinaryData,
&ValueSize );
if( Error != ERROR_SUCCESS ) {
CacheHeap->Free( BinaryData );
return( Error );
}
*Data = BinaryData;
*DataLen = ValueSize;
return( ERROR_SUCCESS );
}
DWORD
REGISTRY_OBJ::GetValue(
LPWSTR ValueName,
LPBYTE Data,
DWORD *DataLen
)
/*++
Routine Description:
Gets a REG_BINARY value.
Arguments:
ValueName : name of the value being retrived.
Data : pointer to a buffer where the data will be read.
Datalen : pointer to location where length of the above buffer is
passed. On return this location will have the length of the
data read.
Return Value:
Windows Error Code.
--*/
{
DWORD Error;
DWORD ValueType;
Error = RegQueryValueExW(
_RegHandle,
ValueName,
0,
&ValueType,
Data,
DataLen );
return( Error );
}
DWORD
REGISTRY_OBJ::SetValue(
LPWSTR ValueName,
LPDWORD Data
)
/*++
Routine Description:
Sets a REG_DWORD value.
Arguments:
ValueName : name of the value being set.
Date : pointer to a DWORD data.
Return Value:
Windows Error Code.
--*/
{
DWORD Error;
Error = RegSetValueExW(
_RegHandle,
ValueName,
0,
REG_DWORD,
(LPBYTE)Data,
sizeof(DWORD) );
return( Error );
}
DWORD
REGISTRY_OBJ::SetValue(
LPWSTR ValueName,
LPWSTR Data,
DWORD StringType
)
/*++
Routine Description:
Sets a REG_SZ or REG_EXPAND_SZ or REG_MULTI_SZ value.
Data : pointer to STRING(s) data.
StringType : type of string data in the above buffer, it should be
either of the following types :
REG_SZ or REG_EXPAND_SZ or REG_MULTI_SZ
Arguments:
ValueName : name of the value being set.
Return Value:
Windows Error Code.
--*/
{
DWORD Error;
Error = RegSetValueExW(
_RegHandle,
ValueName,
0,
StringType,
(LPBYTE)Data,
sizeof(WCHAR) * (wcslen(Data) + 1) );
return( Error );
}
DWORD
REGISTRY_OBJ::SetValue(
LPSTR ValueName,
LPSTR Data,
DWORD DataLen,
DWORD StringType
)
/*++
Routine Description:
Sets a REG_SZ or REG_EXPAND_SZ or REG_MULTI_SZ value.
Data : pointer to STRING(s) data.
DataLen : data length
StringType : type of string data in the above buffer, it should be
either of the following types :
REG_SZ or REG_EXPAND_SZ or REG_MULTI_SZ
Arguments:
ValueName : name of the value being set.
Return Value:
Windows Error Code.
--*/
{
DWORD Error;
Error = RegSetValueEx(
_RegHandle,
ValueName,
0,
StringType,
(LPBYTE)Data,
DataLen );
return( Error );
}
DWORD
REGISTRY_OBJ::SetValue(
LPWSTR ValueName,
LPBYTE Data,
DWORD DataLen
)
/*++
Routine Description:
Sets a REG_BINARY value.
Arguments:
ValueName : name of the value being set.
Return Value:
Windows Error Code.
--*/
{
DWORD Error;
Error = RegSetValueExW(
_RegHandle,
ValueName,
0,
REG_BINARY,
Data,
DataLen );
return( Error );
}
DWORD
REGISTRY_OBJ::FindNextKey(
LPWSTR Key,
DWORD KeySize
)
/*++
Routine Description:
Retrieves the Next subkey name of this key.
Arguments:
Key - pointer to a buffer that receives the subkey name.
KeySize - size of the above buffer in CHARS.
Return Value:
Windows Error Code.
--*/
{
DWORD Error;
DWORD KeyLength;
FILETIME KeyLastWrite;
KeyLength = KeySize * sizeof(WCHAR);
Error = RegEnumKeyExW(
_RegHandle,
_Index,
Key,
&KeyLength,
0, // reserved.
NULL, // class string not required.
0, // class string buffer size.
&KeyLastWrite );
if( Error != ERROR_SUCCESS ) {
return( Error );
}
TcpsvcsDbgAssert( KeyLength <= KeySize );
//
// increament the index to point to the next key.
//
_Index++;
return( ERROR_SUCCESS );
}
DWORD
REGISTRY_OBJ::DeleteKey(
LPWSTR ChildKeyName
)
/*++
Routine Description:
Deletes a subkey node.
Arguments:
ChildKeyName : name of the subkey to be deleted.
Return Value:
Windows Error Code.
--*/
{
DWORD Error;
LPWSTR GChildKeyName[MAX_KEY_SIZE];
REGISTRY_OBJ ChildObj( _RegHandle, ChildKeyName );
Error = ChildObj.GetStatus();
if( Error != ERROR_SUCCESS ) {
return( Error );
}
//
// delete all its subkeys.
//
Error = ChildObj.FindFirstKey(
(LPWSTR)GChildKeyName,
MAX_KEY_SIZE );
while( Error == ERROR_SUCCESS ) {
Error = ChildObj.DeleteKey( (LPWSTR)GChildKeyName );
if( Error != ERROR_SUCCESS ) {
return( Error );
}
Error = ChildObj.FindFirstKey(
(LPWSTR)GChildKeyName,
MAX_KEY_SIZE );
}
if( Error != ERROR_NO_MORE_ITEMS ) {
return( Error );
}
//
// delete this key.
//
Error = RegDeleteKeyW( _RegHandle, (LPWSTR)ChildKeyName );
return( Error );
}
DWORD
REGISTRY_OBJ::FindNextValue(
LPSTR ValueName,
DWORD ValueSize,
LPBYTE Data,
DWORD *DataLen
)
/*++
Routine Description:
Retrieves the Next value name of this key.
Arguments:
ValueName - pointer to a buffer that receives the Value name.
ValueSize - size of the above buffer in CHARS.
Data - pointer to a buffer that receives the Value data.
DataLen - pointer to a buffer that receives data size.
Return Value:
Windows Error Code.
--*/
{
DWORD Error;
DWORD ValueLength;
DWORD ValueType;
ValueLength = ValueSize * sizeof(CHAR);
Error = RegEnumValue(
_RegHandle,
_ValIndex,
ValueName,
&ValueLength,
NULL, // reserved.
&ValueType,
Data,
DataLen );
if( Error != ERROR_SUCCESS ) {
return( Error );
}
TcpsvcsDbgAssert( ValueLength <= ValueSize );
//
// increment the value index to point to the next value.
//
_ValIndex++;
return( ERROR_SUCCESS );
}