|
|
/*++
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 <cache.hxx>
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;
// Don't allow keys or values to be written to current user during
// GUI mode setup because they will get slammed into all profiles.
if (_RegHandle == HKEY_CURRENT_USER && IsInGUIModeSetup()) _dwAccess = BASIC_ACCESS; else _dwAccess = DEFAULT_KEY_ACCESS; return; };
DWORD REGISTRY_OBJ::WorkWith( HKEY ParentHandle, LPTSTR KeyName, DWORD dwFlags, DWORD dwAccess ) /*++
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.
--*/ { if (_RegHandle) { REGCLOSEKEY(_RegHandle); } _Index = 0; _ValIndex = 0; _dwAccess = dwAccess; if (ParentHandle == HKEY_CURRENT_USER && IsInGUIModeSetup()) { // Don't allow anything other than query and enumerate
// when working with HKCU hive during GUI mode setup
_dwAccess &= BASIC_ACCESS; }
_Status = REGOPENKEYEX( ParentHandle, KeyName, 0, _dwAccess, &_RegHandle );
if (_Status == ERROR_FILE_NOT_FOUND && dwFlags == CREATE_KEY_IF_NOT_EXISTS) { REGISTRY_OBJ roTemp(ParentHandle, (LPSTR)NULL); _Status = roTemp.GetStatus(); if (_Status==ERROR_SUCCESS) { _Status = roTemp.Create(KeyName, &_RegHandle); } }
if( _Status != ERROR_SUCCESS ) { _RegHandle = NULL; }
return _Status; }
DWORD REGISTRY_OBJ::WorkWith( REGISTRY_OBJ *ParentObj, LPTSTR KeyName, DWORD dwFlags ) /*++
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.
--*/ { if (_RegHandle) { REGCLOSEKEY(_RegHandle); } _Index = 0; _ValIndex = 0; _dwAccess = ParentObj->GetAccessFlags(); _Status = REGOPENKEYEX( ParentObj->_RegHandle, KeyName, 0, _dwAccess, &_RegHandle );
if (_Status == ERROR_FILE_NOT_FOUND && dwFlags == CREATE_KEY_IF_NOT_EXISTS) { _Status = ParentObj->Create(KeyName, &_RegHandle); }
if( _Status != ERROR_SUCCESS ) { _RegHandle = NULL; }
return _Status; }
DWORD REGISTRY_OBJ::Create( LPTSTR ChildName, HKEY* pChildHandle ) /*++
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;
if (_RegHandle == HKEY_CURRENT_USER && IsInGUIModeSetup()) { _Status = ERROR_ACCESS_DENIED; return _Status; }
_Status = REGCREATEKEYEX( _RegHandle, ChildName, 0, DEFAULT_CLASS, REG_OPTION_NON_VOLATILE, DEFAULT_KEY_ACCESS, NULL, (pChildHandle) ? pChildHandle : &ChildHandle, &KeyDisposition );
if( _Status != ERROR_SUCCESS ) { return( _Status ); }
if( KeyDisposition == REG_CREATED_NEW_KEY ) { #ifndef unix
TcpsvcsDbgPrint(( DEBUG_REGISTRY, "Registry key (%ws) is created.\n", ChildName )); #else
TcpsvcsDbgPrint(( DEBUG_REGISTRY, "Registry key (%s) is created.\n", ChildName )); #endif /* unix */
}
//
// close the child handle before return.
//
if (!pChildHandle) { REGCLOSEKEY( ChildHandle ); }
return( ERROR_SUCCESS ); }
DWORD REGISTRY_OBJ::Create( LPTSTR 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;
if (_RegHandle == HKEY_CURRENT_USER && IsInGUIModeSetup()) { return ERROR_ACCESS_DENIED; }
Error = REGCREATEKEYEX( _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 ) { #ifndef unix
TcpsvcsDbgPrint(( DEBUG_REGISTRY, "Registry key (%ws) is created.\n", ChildName )); #else
TcpsvcsDbgPrint(( DEBUG_REGISTRY, "Registry key (%s) is created.\n", ChildName )); #endif /* unix */
}
*ChildObj = new REGISTRY_OBJ( ChildHandle, (DWORD)ERROR_SUCCESS ); }
return( Error ); }
DWORD REGISTRY_OBJ::Create( LPTSTR 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;
if (_RegHandle == HKEY_CURRENT_USER && IsInGUIModeSetup()) { return ERROR_ACCESS_DENIED; }
Error = REGCREATEKEYEX( _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 ) { #ifndef unix
TcpsvcsDbgPrint(( DEBUG_REGISTRY, "Registry key (%ws) is created.\n", ChildName )); #else
TcpsvcsDbgPrint(( DEBUG_REGISTRY, "Registry key (%s) is created.\n", ChildName )); #endif /* unix */
}
*ChildObj = new REGISTRY_OBJ( ChildHandle, (DWORD)ERROR_SUCCESS ); }
return( Error ); }
DWORD REGISTRY_OBJ::GetValue( LPTSTR 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 = RegQueryValueEx( _RegHandle, ValueName, 0, &ValueType, (LPBYTE)Data, &ValueSize );
// TcpsvcsDbgAssert( ValueSize == sizeof( DWORD ) );
// TcpsvcsDbgAssert( ValueType == REG_DWORD );
return( Error ); }
DWORD REGISTRY_OBJ::GetValue( LPTSTR ValueName, LPTSTR *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 = RegQueryValueEx( _RegHandle, ValueName, 0, &ValueType, StringData, &ValueSize );
if( Error != ERROR_SUCCESS ) { CacheHeap->Free( StringData ); return( Error ); }
#ifdef unix
if (Error == ERROR_SUCCESS) { CHAR szExpand[MAX_PATH+1]; DWORD Length = ExpandEnvironmentStrings((LPTSTR)StringData, (LPTSTR)szExpand, MAX_PATH); if (Length == 0 || Length > MAX_PATH) { Error = GetLastError(); CacheHeap->Free(StringData); return (Error); }
CacheHeap->Free(StringData); StringData = (LPBYTE)CacheHeap->Alloc( Length ); if(StringData == NULL){ return( ERROR_NOT_ENOUGH_MEMORY ); } memcpy(StringData,szExpand,Length+1); } #endif /* unix */
*Data = (LPTSTR)StringData;
if( (ValueType == REG_SZ) || (ValueType == REG_EXPAND_SZ) ) { *NumStrings = 1; } else {
DWORD Strings = 0; LPTSTR StrPtr = (LPTSTR)StringData; DWORD Len;
while( (Len = lstrlen(StrPtr)) != 0 ) { Strings++; StrPtr = StrPtr + Len + 1; }
*NumStrings = Strings; }
return( ERROR_SUCCESS ); }
DWORD REGISTRY_OBJ::GetValue( LPTSTR 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 = RegQueryValueEx( _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( LPTSTR 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 = RegQueryValueEx( _RegHandle, ValueName, 0, &ValueType, Data, DataLen );
#ifdef unix
{ CHAR szExpand[MAX_PATH+1]; DWORD Length = ExpandEnvironmentStrings((LPTSTR)Data, (LPTSTR)szExpand, MAX_PATH); if (Length == 0 || Length > MAX_PATH) { Error = GetLastError(); return (Error); } memcpy(Data,szExpand,Length+1); } #endif /* unix */
return( Error ); }
DWORD REGISTRY_OBJ::SetValue( LPTSTR 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 = RegSetValueEx( _RegHandle, ValueName, 0, REG_DWORD, (LPBYTE)Data, sizeof(DWORD) );
return( Error ); }
DWORD REGISTRY_OBJ::SetValue( LPTSTR ValueName, LPTSTR 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;
UNIX_NORMALIZE_IF_CACHE_PATH((LPTSTR)Data,TEXT("%USERPROFILE%"),ValueName);
Error = RegSetValueEx( _RegHandle, ValueName, 0, StringType, (LPBYTE)Data, sizeof(TCHAR) * (lstrlen(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( LPTSTR 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 = RegSetValueEx( _RegHandle, ValueName, 0, REG_BINARY, Data, DataLen );
return( Error ); }
DWORD REGISTRY_OBJ::FindNextKey( LPTSTR 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(TCHAR); Error = RegEnumKeyEx( _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( LPTSTR ChildKeyName ) /*++
Routine Description:
Deletes a subkey node.
Arguments:
ChildKeyName : name of the subkey to be deleted.
Return Value:
Windows Error Code.
--*/ { DWORD Error; LPTSTR 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( (LPTSTR)GChildKeyName, MAX_KEY_SIZE );
while( Error == ERROR_SUCCESS ) {
Error = ChildObj.DeleteKey( (LPTSTR)GChildKeyName );
if( Error != ERROR_SUCCESS ) { return( Error ); }
Error = ChildObj.FindFirstKey( (LPTSTR)GChildKeyName, MAX_KEY_SIZE ); }
if( Error != ERROR_NO_MORE_ITEMS ) { return( Error ); }
//
// delete this key.
//
Error = RegDeleteKey( _RegHandle, (LPTSTR)ChildKeyName ); return( Error ); }
DWORD REGISTRY_OBJ::DeleteValue( LPTSTR ValueName ) { DWORD Error; Error = RegDeleteValue( _RegHandle, ValueName );
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 ); }
|