windows-nt/Source/XPSP1/NT/shell/ext/shtl/simreg.cpp
2020-09-26 16:20:57 +08:00

636 lines
17 KiB
C++

//+-------------------------------------------------------------------------
//
// File: simreg.h
//
// Contents: CRegFile
//
// Simple Win32/Win16 registry manipulation class
// Copyright (c)1996, Shaun Ivory
// All rights reserved
// Used with permission from Shaun hisself (shauniv)
//
// History: Sep-26-96 Davepl Created
//
//--------------------------------------------------------------------------
#include "shtl.h"
#include "simreg.h"
#if defined(SIMREG_WIN32)
#include <winreg.h>
#endif
#ifndef HKEY_CURRENT_USER
#define HKEY_CURRENT_USER (( HKEY ) 0x80000001 )
#endif
#ifndef HKEY_LOCAL_MACHINE
#define HKEY_LOCAL_MACHINE (( HKEY ) 0x80000002 )
#endif
#ifndef HKEY_USERS
#define HKEY_USERS (( HKEY ) 0x80000003 )
#endif
#ifndef HKEY_PERFORMANCE_DATA
#define HKEY_PERFORMANCE_DATA (( HKEY ) 0x80000004 )
#endif
#ifndef HKEY_CURRENT_CONFIG
#define HKEY_CURRENT_CONFIG (( HKEY ) 0x80000005 )
#endif
#ifndef HKEY_DYN_DATA
#define HKEY_DYN_DATA (( HKEY ) 0x80000006 )
#endif
#if defined(SIMREG_WIN32)
__DATL_INLINE CSimpleReg::CSimpleReg( HKEY keyRoot, const tstring &szRoot, unsigned char forceCreate, LPSECURITY_ATTRIBUTES lpsa)
: m_hSubKey(0), m_hKeyRoot(0), m_bCreate(forceCreate != 0),m_lpsaSecurityAttributes(lpsa), m_bOpenSuccess(FALSE)
{ // Normal constructor
SetRoot( keyRoot, szRoot );
}
#else
__DATL_INLINE CSimpleReg::CSimpleReg( HKEY keyRoot, const tstring &szRoot, unsigned char forceCreate)
: m_hSubKey(0), m_hKeyRoot(0), m_bCreate(forceCreate != 0)
{ // Normal constructor
SetRoot( keyRoot, szRoot );
}
#endif
__DATL_INLINE unsigned char CSimpleReg::Assign( const CSimpleReg &other )
{
#if defined(SIMREG_WIN32)
SecurityAttributes(other.SecurityAttributes());
#endif
m_bCreate = other.ForceCreate();
SetRoot( other.GetRootKey(), other.SubKeyName() );
return m_bOpenSuccess;
}
__DATL_INLINE CSimpleReg::CSimpleReg( const CSimpleReg &other )
: m_hSubKey(0), m_hKeyRoot(0), m_bOpenSuccess(FALSE)
{
Assign( other );
}
__DATL_INLINE CSimpleReg::CSimpleReg(void)
: m_bOpenSuccess(0), m_hSubKey(0), m_hKeyRoot(0)
{
#if defined(SIMREG_WIN32)
m_lpsaSecurityAttributes = NULL;
#endif
}
__DATL_INLINE CSimpleReg& CSimpleReg::operator=(const CSimpleReg& other)
{ // Assignment operator
Assign(other);
return (*this);
}
__DATL_INLINE CSimpleReg::~CSimpleReg(void)
{ // Destructor
Close();
}
__DATL_INLINE unsigned char CSimpleReg::ForceCreate( unsigned char create )
{ // Force creation of a key, if it doesn't exist
unsigned char Old = m_bCreate;
m_bCreate = (create != 0);
Open();
return (Old);
}
__DATL_INLINE unsigned long CSimpleReg::Size( const tstring &key )
{
if (!*this)
return (0);
DWORD dwType = REG_SZ;
DWORD dwSize = 0;
LONG Ret;
#if defined(SIMREG_WIN32)
Ret = RegQueryValueEx( m_hSubKey, Totstring(key), NULL, &dwType, NULL, &dwSize);
#else
Ret = RegQueryValue( m_hSubKey, Totstring(key), NULL, (LONG FAR *)&dwSize);
#endif
if (Ret==ERROR_SUCCESS)
{
#if defined(UNICODE) || defined(_UNICODE)
if (dwType == REG_SZ || dwType == REG_EXPAND_SZ || dwType == REG_MULTI_SZ || dwType == REG_LINK || dwType == REG_RESOURCE_LIST)
return (dwSize / 2);
#else
return (dwSize);
#endif
}
return (0);
}
__DATL_INLINE unsigned long CSimpleReg::Type( const tstring &key )
{
if (!*this)
return (0);
DWORD dwType = REG_SZ;
DWORD dwSize = 0;
LONG Ret;
#if defined(SIMREG_WIN32)
Ret = RegQueryValueEx( m_hSubKey, Totstring(key), NULL, &dwType, NULL, &dwSize);
#else
Ret = RegQueryValue( m_hSubKey, Totstring(key), NULL, (LONG FAR *)&dwSize);
#endif
if (Ret==ERROR_SUCCESS)
{
return (dwType);
}
return (0);
}
__DATL_INLINE unsigned char CSimpleReg::Query( const tstring &key, LPTSTR szValue, unsigned short maxLen )
{
if (!*this)
return (0);
DWORD dwType = REG_SZ;
DWORD dwSize = maxLen;
LONG Ret;
#if defined(SIMREG_WIN32)
Ret = RegQueryValueEx( m_hSubKey, Totstring(key), NULL, &dwType, (LPBYTE)szValue, &dwSize);
#else
Ret = RegQueryValue( m_hSubKey, Totstring(key), szValue, (LONG FAR *)&dwSize);
#endif
return (Ret==ERROR_SUCCESS);
}
__DATL_INLINE unsigned char CSimpleReg::Query( const tstring &key, tstring &value, unsigned short maxLen )
{ // Get a REG_SZ (string) from the specified sub-key
if (!*this)
return (0);
if (!maxLen)
maxLen = (unsigned short)(Size( key ) + 1);
if (!maxLen)
maxLen = 1;
LPTSTR Buffer = new TCHAR[maxLen];
DWORD dwType = REG_SZ;
DWORD dwSize = maxLen;
LONG Ret;
#if defined(SIMREG_WIN32)
Ret = RegQueryValueEx( m_hSubKey, Totstring(key), NULL, &dwType, (LPBYTE)Buffer, &dwSize);
#else
Ret = RegQueryValue( m_hSubKey, Totstring(key), Buffer, (LONG FAR *)&dwSize);
#endif
if (Ret==ERROR_SUCCESS)
{
value = tstring(Buffer);
}
delete[] Buffer;
return (Ret==ERROR_SUCCESS);
}
__DATL_INLINE unsigned char CSimpleReg::Query( const tstring &key, DWORD &value )
{ // Get a REG_DWORD (unsigned long int) from the specified sub-key
if (!*this)
return (0);
#if defined(SIMREG_WIN32)
DWORD Value;
DWORD dwType = REG_DWORD;
DWORD dwSize = sizeof(DWORD);
LONG Ret;
Ret = RegQueryValueEx( m_hSubKey, Totstring(key), NULL, &dwType, (LPBYTE)&Value, &dwSize);
if (Ret==ERROR_SUCCESS)
{
value = Value;
}
return (Ret==ERROR_SUCCESS);
#else
DWORD temp = value;
if (QueryBin( key, &temp, sizeof(temp)))
{
value = temp;
return (TRUE);
}
return (FALSE);
#endif
}
__DATL_INLINE unsigned char CSimpleReg::Query( const tstring &key, int &value )
{ // Get a REG_DWORD (unsigned long int) from the specified sub-key
DWORD Temp;
if (Query(key,Temp))
{
value = (int)Temp;
return (TRUE);
}
return (FALSE);
}
__DATL_INLINE unsigned char CSimpleReg::Query( const tstring &key, LONG &value )
{ // Get a REG_DWORD (unsigned long int) from the specified sub-key
DWORD Temp;
if (Query(key,Temp))
{
value = (LONG)Temp;
return (TRUE);
}
return (FALSE);
}
__DATL_INLINE unsigned char CSimpleReg::Query( const tstring &key, WORD &value )
{ // Get a REG_DWORD (unsigned long int) from the specified sub-key
DWORD Temp;
if (Query(key,Temp))
{
value = (WORD)Temp;
return (TRUE);
}
return (FALSE);
}
__DATL_INLINE unsigned char CSimpleReg::Query( const tstring &key, BYTE &value )
{ // Get a REG_DWORD (unsigned long int) from the specified sub-key
DWORD Temp;
if (Query(key,Temp))
{
value = (BYTE)Temp;
return (TRUE);
}
return (FALSE);
}
#ifdef SIMREG_WIN32
__DATL_INLINE unsigned char CSimpleReg::SetBin( const tstring &key, void *value, DWORD size )
{
if (!*this)
return (0);
LONG Ret;
Ret = RegSetValueEx( m_hSubKey, Totstring(key), 0, REG_BINARY, (LPBYTE)value, size );
return (Ret==ERROR_SUCCESS);
}
__DATL_INLINE unsigned char CSimpleReg::QueryBin( const tstring &key, void *value, DWORD size )
{
if (!*this)
return (0);
DWORD dwType = REG_BINARY;
DWORD dwSize = size;
LONG Ret;
char *Value = new char[size];
Ret = RegQueryValueEx( m_hSubKey, Totstring(key), NULL, &dwType, (LPBYTE)Value, &dwSize);
if (dwType != REG_BINARY)
{
delete[] Value;
return (0);
}
if (dwSize != size)
{
delete[] Value;
return (0);
}
if (Ret==ERROR_SUCCESS)
{
memcpy( value, Value, size );
}
delete[] Value;
return (Ret==ERROR_SUCCESS);
}
#else
__DATL_INLINE unsigned char CSimpleReg::SetBin( const tstring &key, void *value, DWORD size )
{
if (!*this)
return (0);
unsigned char *Value = (unsigned char*)value;
tstring Str;
char Byte[4];
for (DWORD i=0;i<size;i++)
{
wsprintf( Byte, "%02X ", Value[i] );
Str = Str + Byte;
}
return (Set( key, Str ));
}
__DATL_INLINE unsigned char CSimpleReg::QueryBin( const tstring &key, void *value, DWORD size )
{
if (!*this)
return (0);
unsigned char *Value = (unsigned char *)value;
tstring Str;
if ((unsigned char)Query( key, Str, (unsigned short)(size * 3 + 1))==0)
{
return (FALSE);
}
if (strlen((const char *)Str) != size * 3)
{
return (FALSE);
}
tstring Temp;
while (Str.length())
{
Temp = Str.Left( 3 );
Str = Str.Right( strlen((const char *)Str) - 3 );
*Value = (unsigned char)strtoul((const char *)Temp,NULL,16);
Value++;
}
return (TRUE);
}
#endif
__DATL_INLINE unsigned char CSimpleReg::Set( const tstring &key, const tstring &value )
{ // Set a REG_SZ value for the specified key.
if (!*this)
return (0);
LONG Ret;
#if defined(SIMREG_WIN32)
Ret = RegSetValueEx( m_hSubKey, Totstring(key), 0, REG_SZ, (LPBYTE)Totstring(value), value.length()+1 );
#else
Ret = RegSetValue( m_hSubKey, (LPCSTR)Totstring(key), REG_SZ, (LPCSTR)Totstring(value), value.length()+1 );
#endif
return (Ret==ERROR_SUCCESS);
}
__DATL_INLINE unsigned char CSimpleReg::Set( const tstring &key, DWORD value )
{ // Set a REG_SZ value for the specified key.
if (!*this)
return (0);
#if defined(SIMREG_WIN32)
LONG Ret;
Ret = RegSetValueEx( m_hSubKey, Totstring(key), 0, REG_DWORD, (LPBYTE)&value, sizeof(DWORD) );
return (Ret==ERROR_SUCCESS);
#else
return (SetBin( key, &value, sizeof(DWORD)));
#endif
}
__DATL_INLINE unsigned char CSimpleReg::Open(void)
{ // Open the specified sub key of the open root.
HKEY hKey;
LONG Ret;
Close();
if (m_bCreate)
{
#if defined(SIMREG_WIN32)
DWORD CreatedNewKey;
if ((Ret = RegCreateKeyEx( m_hKeyRoot, Totstring(m_SubKeyName), 0, TEXT(""), REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, SecurityAttributes(), &hKey, &CreatedNewKey )) == ERROR_SUCCESS)
#else
if ((Ret = RegCreateKey( m_hKeyRoot, Totstring(m_SubKeyName), &hKey )) == ERROR_SUCCESS)
#endif
{
m_hSubKey = hKey;
m_bOpenSuccess = 1;
}
}
else
{
#if defined(SIMREG_WIN32)
if ((Ret = RegOpenKeyEx( m_hKeyRoot, Totstring(m_SubKeyName), 0, KEY_ALL_ACCESS, &hKey )) == ERROR_SUCCESS)
#else
if ((Ret = RegOpenKey( m_hKeyRoot, Totstring(m_SubKeyName), &hKey )) == ERROR_SUCCESS)
#endif
{
m_hSubKey = hKey;
m_bOpenSuccess = 1;
}
}
return (m_bOpenSuccess);
}
__DATL_INLINE unsigned char CSimpleReg::Close(void)
{ // If open, close key.
if (m_bOpenSuccess)
RegCloseKey(m_hSubKey);
m_bOpenSuccess = 0;
return (1);
}
__DATL_INLINE unsigned char CSimpleReg::SetRoot( HKEY keyClass, const tstring &newRoot )
{ // Set the root class and key, open.
m_hKeyRoot = GetWin16HKey(keyClass);
m_SubKeyName = newRoot;
return (Open());
}
__DATL_INLINE unsigned char CSimpleReg::Delete( HKEY root, const tstring &key )
{
return (RegDeleteKey(GetWin16HKey(root), Totstring(key)) == ERROR_SUCCESS);
}
__DATL_INLINE DWORD CSimpleReg::CountKeys(void)
{
#if defined(SIMREG_WIN32)
TCHAR Class[256]=TEXT("");
DWORD ClassSize = sizeof(Class)/sizeof(Class[0]);
DWORD subKeyCount=0;
RegQueryInfoKey(GetSubKey(),Class,&ClassSize,NULL,&subKeyCount,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
return (subKeyCount);
#else
char Name[256];
DWORD NameSize;
DWORD subKeyCount=0;
for (int i=0;;i++)
{
NameSize = sizeof(Name) / sizeof(Name[0]);
if (RegEnumKey(GetSubKey(),i,Name,NameSize) != ERROR_SUCCESS)
break;
subKeyCount++;
}
return (subKeyCount);
#endif
}
__DATL_INLINE int CSimpleReg::DoRecurseKeys( HKEY key, const tstring &root, SimRegKeyEnumProc enumProc, void *extraInfo, int level, int recurseOrder, int failOnOpenError )
{
TCHAR Name[256]=TEXT("");
DWORD NameSize;
#if defined(SIMREG_WIN32)
TCHAR Class[256]=TEXT("");
DWORD ClassSize;
FILETIME FileTime;
#endif
CSimpleReg reg(key,root);
LONG res;
if (!reg.OK())
{
return (failOnOpenError ? 0 : 1);
}
DWORD subKeyCount = reg.CountKeys();
for (DWORD i=subKeyCount;i>0;i--)
{
NameSize = sizeof(Name)/sizeof(Name[0]);
#if defined(SIMREG_WIN32)
ClassSize = sizeof(Class)/sizeof(Class[0]);
if ((res=RegEnumKeyEx(reg.GetSubKey(),i-1,Name,&NameSize,NULL,Class,&ClassSize,&FileTime)) != ERROR_SUCCESS)
#else
if ((res=RegEnumKey(reg.GetSubKey(),i-1,Name,NameSize)) != ERROR_SUCCESS)
#endif
{
break;
}
CKeyEnumInfo EnumInfo;
EnumInfo.Name = Name;
EnumInfo.Root = reg.GetSubKey();
EnumInfo.Level = level;
EnumInfo.ExtraData = extraInfo;
if (enumProc && recurseOrder==PreOrder)
if (!enumProc(EnumInfo))
return (0);
if (!DoRecurseKeys(reg.GetSubKey(),Name,enumProc,extraInfo,level+1,recurseOrder, failOnOpenError))
return (0);
if (enumProc && recurseOrder==PostOrder)
if (!enumProc(EnumInfo))
return (0);
}
return (1);
}
__DATL_INLINE int CSimpleReg::DoEnumKeys( HKEY key, const tstring &root, SimRegKeyEnumProc enumProc, void *extraInfo, int failOnOpenError )
{
TCHAR Name[256]=TEXT("");
DWORD NameSize;
#if defined(SIMREG_WIN32)
TCHAR Class[256]=TEXT("");
DWORD ClassSize;
FILETIME FileTime;
#endif
CSimpleReg reg(key,root);
LONG res;
if (!reg.OK())
{
return (failOnOpenError ? 0 : 1);
}
DWORD subKeyCount = reg.CountKeys();
for (DWORD i=subKeyCount;i>0;i--)
{
NameSize = sizeof(Name)/sizeof(Name[0]);
#if defined(SIMREG_WIN32)
ClassSize = sizeof(Class)/sizeof(Class[0]);
if ((res=RegEnumKeyEx(reg.GetSubKey(),i-1,Name,&NameSize,NULL,Class,&ClassSize,&FileTime)) != ERROR_SUCCESS)
#else
if ((res=RegEnumKey(reg.GetSubKey(),i-1,Name,NameSize)) != ERROR_SUCCESS)
#endif
{
break;
}
CKeyEnumInfo EnumInfo;
EnumInfo.Name = Name;
EnumInfo.Root = reg.GetSubKey();
EnumInfo.Level = 0;
EnumInfo.ExtraData = extraInfo;
if (!enumProc(EnumInfo))
return (0);
}
return (1);
}
__DATL_INLINE int CSimpleReg::RecurseKeys( SimRegKeyEnumProc enumProc, void *extraInfo, int recurseOrder, int failOnOpenError )
{
return (DoRecurseKeys(GetSubKey(), TEXT(""), enumProc, extraInfo, 0, recurseOrder, failOnOpenError ));
}
__DATL_INLINE int CSimpleReg::EnumKeys( SimRegKeyEnumProc enumProc, void *extraInfo, int failOnOpenError )
{
return (DoEnumKeys(GetSubKey(), TEXT(""), enumProc, extraInfo, failOnOpenError ));
}
__DATL_INLINE HKEY CSimpleReg::GetHkeyFromName( const tstring &Name )
{
static struct
{
LPCTSTR Name;
HKEY Key;
} KeyNames[] =
{
{ TEXT("HKEY_CLASSES_ROOT"), HKEY_CLASSES_ROOT},
{ TEXT("HKEY_CURRENT_USER"), HKEY_CURRENT_USER},
{ TEXT("HKEY_LOCAL_MACHINE"), HKEY_LOCAL_MACHINE},
{ TEXT("HKEY_USERS"), HKEY_USERS},
{ TEXT("HKEY_CURRENT_CONFIG"), HKEY_CURRENT_CONFIG},
{ TEXT("HKEY_DYN_DATA"), HKEY_DYN_DATA},
{ TEXT("HKCR"), HKEY_CLASSES_ROOT},
{ TEXT("HKCU"), HKEY_CURRENT_USER},
{ TEXT("HKLM"), HKEY_LOCAL_MACHINE},
{ TEXT("HKU"), HKEY_USERS},
{ TEXT("HKCC"), HKEY_CURRENT_CONFIG},
{ TEXT("HKDD"), HKEY_DYN_DATA},
{ NULL, NULL}
};
for (int i=0;KeyNames[i].Name;i++)
{
if (!lstrcmpi(Totstring(Name),KeyNames[i].Name))
return (KeyNames[i].Key);
}
return (INVALID_HKEY);
}
__DATL_INLINE int CSimpleReg::DeleteEnumKeyProc( CSimpleReg::CKeyEnumInfo &enumInfo )
{
return (CSimpleReg::Delete( enumInfo.Root, enumInfo.Name ));
}
__DATL_INLINE int CSimpleReg::DeleteRecursively( HKEY root, const tstring &name )
{
if (CSimpleReg( root, name ).RecurseKeys( DeleteEnumKeyProc, NULL, CSimpleReg::PostOrder ))
return (CSimpleReg::Delete( root, name ));
return (0);
}
__DATL_INLINE HKEY CSimpleReg::GetWin16HKey( HKEY key )
{
#if !defined(SIMREG_WIN32)
if (key == HKEY_CURRENT_USER ||
key == HKEY_LOCAL_MACHINE ||
key == HKEY_USERS ||
key == HKEY_CURRENT_CONFIG ||
key == HKEY_DYN_DATA)
return (HKEY_CLASSES_ROOT);
#endif
return (key);
}
__DATL_INLINE int CSimpleReg::EnumValues( SimRegValueEnumProc enumProc, void *extraInfo )
{
TCHAR Name[256];
DWORD Size;
DWORD Type;
int Result = 1;
for (int i=0;;i++)
{
Size = sizeof(Name) / sizeof(Name[0]);
if (RegEnumValue(GetSubKey(),i,Name,&Size,NULL,&Type,NULL,NULL) != ERROR_SUCCESS)
break;
CValueEnumInfo info;
info.Name = Name;
info.Type = Type;
info.Size = Size;
info.ExtraData = extraInfo;
if (enumProc)
{
if (!enumProc(info))
{
Result = 0;
break;
}
}
}
return (Result);
}