//+--------------------------------------------------------------------------- // // Copyright (C) 1992, Microsoft Corporation. // // File: dsysreg.hxx // // Contents: Definitions of classes for manipulating registry entries. // // Classes: CRegKey - class for registry key objects // CRegValue - base class for registry value objects // CRegSZ - derived class for registry string values // CRegDWORD - derived class for registry dword values // CRegBINARY - derived class for registry binary values // CRegMSZ - derived class for registry multi-string values // // History: 09/30/92 Rickhi Created // 09/22/93 AlokS Took out exception throwing code // and added proper return code for // each method. // // 07/26/94 AlokS Made it lightweight for normal set/get // operations. Threw out all exception code // // Notes: CRegKey can use another CRegKey as a parent, so you can // build a tree of keys. To kick things off, you can give one // of the default registry keys like HKEY_CURRENT_USER. When // you do this, the GetParent method returns NULL. Currently // however, no ptrs are kept to child and sibling keys. // // CRegValue is a base class for dealing with registry values. // The other classes (except CRegKey) are for dealing with a // specific type of registry value in the native data format. // For example, CRegDWORD lets you call methods just providing // a dword. The methods take care of figuring out the size and // casting the dword to a ptr to bytes, etc for use in the Win32 // registry APIs. // // For any registry type not defined here, you can always resort // to using the CRegValue base class directly, though you then // must call GetValue or SetValue methods explicitly. // // Sample Usage: // // The following reads the username in the ValueID UserName // within the key HKEY_CURRENT_USER\LogonInfo. It then changes // it to Rickhi. It also sets the password valueid in the // the same key to foobar. // // #include // // // open the registry key // CRegKey rkLogInfo(HKEY_CURRENT_USER, L"LogonInfo"); // // // read the user name // LPWSTR pwszUserName; // CRegSZ rszUserName(&rkLogInfo, L"UserName", pwszUserName); // rszUserName.SetString(L"Rickhi"); // // // set the password // CRegSZ rszPassWord(&rkLogInfo, L"PassWord", L"foobar"); // //---------------------------------------------------------------------------- #ifndef __DSYSREG_HXX__ #define __DSYSREG_HXX__ #include "wcbuffer.hxx" // to simplify error creation #define Creg_ERROR(x) (x) // forward declarations for use in the following structures class CRegValue; class CRegKey; // structure for enumerating subkeys of a key typedef struct _SRegKeySet { ULONG cKeys; CRegKey *aprkKey[1]; } SRegKeySet; // structure for enumerating values within a key typedef struct _SRegValueSet { ULONG cValues; CRegValue *aprvValue[1]; } SRegValueSet; // structure for dealing with multi-string values typedef struct _SMultiStringSet { ULONG cStrings; LPWSTR apwszString[1]; } SMultiStringSet; //+------------------------------------------------------------------------- // // Class: CRegKey // // Purpose: class for abstracting Registry Keys // // Interface: CRegKey - constructor for a registry key object // ~CRegKey - destructor for a registry key object // GetParentHandle - returns parent key's handle // GetHandle - returns this key's handle // GetName - returns key path // Delete - deletes the key from the registry // EnumValues - enumerate values stored in the key // EnumKeys - enumerates subkeys of the key // NotifyChange - sets up change notification for the key // QueryErrorStatus - Should be used to determine if constructor // completed successfully or not // History: 09/30/92 Rickhi Created // // Notes: // //-------------------------------------------------------------------------- class CRegKey { public: // constructor using HKEY for parent // Mode: Create key if not present CRegKey( HKEY hkParent, const LPWSTR pwszPath, // remaining parameters are optional REGSAM samDesiredAccess = KEY_ALL_ACCESS, const LPWSTR pwszClass = NULL, DWORD dwOptions = REG_OPTION_NON_VOLATILE, DWORD *pdwDisposition = NULL, const LPSECURITY_ATTRIBUTES pSecurityAttributes = NULL ); // constructor using CRegKey as parent // Mode: Create key if not present CRegKey(const CRegKey& crkParent, const LPWSTR pwszPath, // remaining parameters are optional REGSAM samDesiredAccess = KEY_ALL_ACCESS, const LPWSTR pwszClass = NULL, DWORD dwOptions = REG_OPTION_NON_VOLATILE, DWORD *pdwDisposition = NULL, const LPSECURITY_ATTRIBUTES pSecurityAttributes = NULL ); // Constructor using HKEY for parent // Mode: Simply Open the key, if exists CRegKey ( HKEY hkParent, DWORD *pdwErr, const LPWSTR pwszPath, REGSAM samDesiredAccess = KEY_ALL_ACCESS ); // Constructor using CRegKey as parent // Mode: Simply open the key, if exists CRegKey (const CRegKey& crkParent, DWORD *pdwErr, const LPWSTR pwszPath, REGSAM samDesiredAccess = KEY_ALL_ACCESS ); // Destructor - Closes registry key ~CRegKey(void); HKEY GetHandle(void) const; const LPWSTR GetName(void) const; DWORD Delete(void); DWORD DeleteChildren(void); DWORD EnumValues(SRegValueSet **pprvs); DWORD EnumKeys(SRegKeySet **pprks); // This method can be called to determine if // Object is in sane state or not DWORD QueryErrorStatus () const { return _dwErr ; } // Static routine which frees memory allocated during EnumValues/Keys static void MemFree ( void * pv ) { delete [] (BYTE*)pv; } private: DWORD CreateKey( HKEY hkParent, const LPWSTR pwszPath, REGSAM samDesiredAccess, const LPWSTR pwszClass, DWORD dwOptions, DWORD *pdwDisposition, const LPSECURITY_ATTRIBUTES pSecurityAttributes ); DWORD OpenKey ( HKEY hkParent, const LPWSTR pwszPath, REGSAM samDesiredAccess ); HKEY _hkParent; // Handle to parent HKEY _hkThis; // handle for this key CWCHARBuffer _cwszName; // Buffer containing the registry path // path from parent key to this key DWORD _dwErr; // Internal error status }; inline HKEY CRegKey::GetHandle(void) const { return _hkThis; } inline const LPWSTR CRegKey::GetName(void) const { return (const LPWSTR) (LPWSTR)_cwszName; } //+------------------------------------------------------------------------- // // Class: CRegValue // // Purpose: base class for abstracting Registry Values // // Interface: CRegValue - constructor for value // ~CRegValue - destructor for value // GetKeyHandle - returns handle for parent key // GetValueID - returns the ValueID name // GetTypeCode - returns the TypeCode of the data // GetValue - returns the data associated with the value // SetValue - sets the data associated with the value // Delete - deletes the value from the registry // QueryErrorStatus - Should be used to determine if constructor // completed successfully or not // // History: 09/30/92 Rickhi Created // // Notes: This is a base class from which more specific classes are // derived for each of the different registry value types. // //-------------------------------------------------------------------------- class CRegValue { public: CRegValue(const CRegKey& crkParentKey, const LPWSTR pwszValueID); ~CRegValue(void){;}; HKEY GetParentHandle(void) const; const LPWSTR GetValueID(void) const; VOID Delete(void); // Caller supplies buffer DWORD GetValue(LPBYTE pbData, ULONG *pcbData, DWORD *pdwTypeCode); DWORD SetValue(const LPBYTE pbData, ULONG cbData, DWORD dwTypeCode); virtual DWORD QueryErrorStatus (void) const { return _dwErr ; } private: CWCHARBuffer _cwszValueID; HKEY _hkParent; DWORD _dwErr ; }; //+------------------------------------------------------------------------- // // Member: CRegValue::CRegValue // // Purpose: constructor for base registry value // // Arguments: [prkParent] - ptr to parent CRegKey for the key // [pwszValueID] - the valueID name for the value // // Signals: nothing // // Returns: nothing // // History: 09/30/92 Rickhi Created // // Notes: // //-------------------------------------------------------------------------- inline CRegValue::CRegValue(const CRegKey& crkParent, const LPWSTR pwszValueID) : _hkParent (crkParent.GetHandle()), _dwErr(crkParent.QueryErrorStatus()) { _cwszValueID.Set(pwszValueID); } inline HKEY CRegValue::GetParentHandle(void) const { return _hkParent; } inline const LPWSTR CRegValue::GetValueID(void) const { return (const LPWSTR) (LPWSTR) _cwszValueID; } inline VOID CRegValue::Delete(void) { _dwErr = RegDeleteValue( _hkParent, _cwszValueID ); } //+------------------------------------------------------------------------- // // Class: CRegSZ // // Purpose: Derived class for abstracting Registry string Values // // Interface: CRegSZ - constructor for registry value using string // ~CRegSZ - destructor for registry string object // GetString - returns the string // SetString - sets a new string value // QueryErrorStatus - Should be used to determine if constructor // completed successfully or not // // History: 09/30/92 Rickhi Created // // Notes: Derived from CRegValue. // // There are three constructors. The first is used if you want // to create a new value or overwrite the existing value data. // The second is used if you want to open an existing value // and read it's data. The third is used if you just want to // make an object without doing any read/write of the data yet. // In all three cases, you can always use any of the Get/Set // operations on the object at a later time. // //-------------------------------------------------------------------------- class CRegSZ : public CRegValue { public: // create/write value constructor CRegSZ(const CRegKey &crkParent, const LPWSTR pwszValueID, const LPWSTR pwszData ); // io-less constructor - used by enumerator CRegSZ(const CRegKey &crkParent, const LPWSTR pwszValueID ); ~CRegSZ(void){;}; DWORD SetString(const LPWSTR pwszData); // Caller supplies buffer (supply the buffer size in bytes) DWORD GetString( LPWSTR pwszData, ULONG *pcbData); DWORD GetTypeCode(void); DWORD QueryErrorStatus(void) const { return _dwErr ; } private: DWORD _dwErr; }; //+------------------------------------------------------------------------- // // Member: CRegSZ::CRegSZ // // Purpose: Constructor for registry string value // // History: 09/30/92 Rickhi Created // // Notes: // //-------------------------------------------------------------------------- inline CRegSZ::CRegSZ(const CRegKey &crkParent, const LPWSTR pwszValueID, const LPWSTR pwszData) : CRegValue(crkParent, pwszValueID) { if (ERROR_SUCCESS == (_dwErr = CRegValue::QueryErrorStatus())) _dwErr = SetString(pwszData); } inline CRegSZ::CRegSZ(const CRegKey &crkParent, const LPWSTR pwszValueID) : CRegValue(crkParent, pwszValueID) { // automatic actions in header are sufficient _dwErr = CRegValue::QueryErrorStatus(); } inline DWORD CRegSZ::SetString(const LPWSTR pwszData) { return SetValue((LPBYTE)pwszData, (wcslen(pwszData)+1)*sizeof(WCHAR), REG_SZ); } inline DWORD CRegSZ::GetString(LPWSTR pwszData, ULONG* pcbData) { DWORD dwTypeCode; return GetValue((LPBYTE)pwszData, pcbData, &dwTypeCode); } inline DWORD CRegSZ::GetTypeCode(void) { return REG_SZ; } //+------------------------------------------------------------------------- // // Class: CRegMSZ // // Purpose: Derived class for abstracting Registry multi-string Values // // Interface: CRegMSZ - constructor for registry value using string // ~CRegMSZ - destructor for registry string object // GetString - returns the string // SetString - sets a new string value // QueryErrorStatus - Should be used to determine if constructor // completed successfully or not // // History: 09/30/92 Rickhi Created // // Notes: Derived from CRegValue. // // There are three constructors. The first is used if you want // to create a new value or overwrite the existing value data. // The second is used if you want to open an existing value // and read it's data. The third is used if you just want to // make an object without doing any read/write of the data yet. // In all three cases, you can always use any of the Get/Set // operations on the object at a later time. // //-------------------------------------------------------------------------- class CRegMSZ : public CRegValue { public: // create/write value constructor CRegMSZ(const CRegKey &crkParent, const LPWSTR pwszValueID, const LPWSTR pwszData ); // io-less constructor - used by enumerator CRegMSZ(const CRegKey &crkParent, const LPWSTR pwszValueID ); ~CRegMSZ(void){;}; DWORD SetString(const LPWSTR pwszData); // Caller supplies buffer (supply the buffer size in bytes) DWORD GetString( LPWSTR pwszData, ULONG *pcbData); DWORD GetTypeCode(void); DWORD QueryErrorStatus(void) const { return _dwErr ; } private: DWORD _dwErr; }; //+------------------------------------------------------------------------- // // Member: CRegMSZ::CRegMSZ // // Purpose: Constructor for registry string value // // History: 09/30/92 Rickhi Created // // Notes: // //-------------------------------------------------------------------------- inline CRegMSZ::CRegMSZ(const CRegKey &crkParent, const LPWSTR pwszValueID, const LPWSTR pwszData) : CRegValue(crkParent, pwszValueID) { if (ERROR_SUCCESS == (_dwErr = CRegValue::QueryErrorStatus())) _dwErr = SetString(pwszData); } inline CRegMSZ::CRegMSZ(const CRegKey &crkParent, const LPWSTR pwszValueID) : CRegValue(crkParent, pwszValueID) { // automatic actions in header are sufficient _dwErr = CRegValue::QueryErrorStatus(); } inline DWORD CRegMSZ::SetString(const LPWSTR pwszData) { DWORD cwLen, cbData; LPWSTR pwszNextString; for (pwszNextString = pwszData, cbData = 0; *pwszNextString != UNICODE_NULL; pwszNextString += cwLen) { cwLen = wcslen(pwszNextString) + 1; cbData += (cwLen * sizeof(WCHAR)); } cbData += sizeof(UNICODE_NULL); return SetValue((LPBYTE)pwszData, cbData, REG_MULTI_SZ); } inline DWORD CRegMSZ::GetString(LPWSTR pwszData, ULONG* pcbData) { DWORD dwTypeCode; return GetValue((LPBYTE)pwszData, pcbData, &dwTypeCode); } inline DWORD CRegMSZ::GetTypeCode(void) { return REG_MULTI_SZ; } //+------------------------------------------------------------------------- // // Class: CRegDWORD // // Purpose: Derived class for abstracting Registry dword Values // // Interface: CRegDWORD - constructor for registry value using dword // ~CRegDWORD - destructor for registry dword object // GetDword - returns the dword // SetDword - sets a new dword value // QueryErrorStatus - Should be used to determine if constructor // completed successfully or not // // History: 09/30/92 Rickhi Created // // Notes: Derived from CRegValue. // // There are three constructors. The first is used if you want // to create a new value or overwrite the existing value data. // The second is used if you want to open an existing value // and read it's data. The third is used if you just want to // make an object without doing any read/write of the data yet. // In all three cases, you can always use any of the Get/Set // operations on the object at a later time. // //-------------------------------------------------------------------------- class CRegDWORD : public CRegValue { public: // create/write value constructor CRegDWORD(const CRegKey &crkParent, const LPWSTR pwszValueID, DWORD dwData); // open/read value constructor CRegDWORD(const CRegKey &crkParent, const LPWSTR pwszValueID, DWORD *pdwData); // io-less constructor - used by enumerator CRegDWORD( const CRegKey &crkParent, const LPWSTR pwszValueID); ~CRegDWORD(void){;}; DWORD SetDword(DWORD dwData); DWORD GetDword(DWORD *pdwData); DWORD GetTypeCode(void) ; DWORD QueryErrorStatus(void) const { return _dwErr ; } private: DWORD _dwErr; }; //+------------------------------------------------------------------------- // // Member: CRegDWORD::CRegDWORD // // Purpose: Constructor for registry dword value // // History: 09/30/92 Rickhi Created // // Notes: // //-------------------------------------------------------------------------- inline CRegDWORD::CRegDWORD(const CRegKey &crkParent, const LPWSTR pwszValueID, DWORD dwData) : CRegValue(crkParent, pwszValueID) { if (ERROR_SUCCESS == (_dwErr = CRegValue::QueryErrorStatus())) _dwErr = SetDword(dwData); } inline CRegDWORD::CRegDWORD(const CRegKey &crkParent, const LPWSTR pwszValueID, DWORD *pdwData) : CRegValue(crkParent, pwszValueID) { if (ERROR_SUCCESS == (_dwErr = CRegValue::QueryErrorStatus())) _dwErr = GetDword(pdwData); } inline CRegDWORD::CRegDWORD(const CRegKey &crkParent, const LPWSTR pwszValueID) : CRegValue(crkParent, pwszValueID) { // automatic actions in header are sufficient _dwErr = CRegValue::QueryErrorStatus(); } inline DWORD CRegDWORD::GetDword(DWORD *pdwData) { DWORD dwTypeCode; DWORD dwErr; ULONG cbData= sizeof(DWORD); dwErr = GetValue((LPBYTE)pdwData, &cbData, &dwTypeCode); return (dwErr); } inline DWORD CRegDWORD::SetDword(DWORD dwData) { return SetValue((LPBYTE)&dwData, sizeof(DWORD), REG_DWORD); } inline DWORD CRegDWORD::GetTypeCode(void) { return REG_DWORD; } //+------------------------------------------------------------------------- // // Class: CRegBINARY // // Purpose: Derived class for abstracting Registry binary Values // // Interface: CRegBINARY - constructor for registry value using binary data // ~CRegBINARY - destructor for registry binary data object // GetBinary - returns the binary data // SetBinary - sets a new binary data value // QueryErrorStatus - Should be used to determine if constructor // completed successfully or not // // History: 09/30/92 Rickhi Created // // Notes: Derived from CRegValue. // // There are three constructors. The first is used if you want // to create a new value or overwrite the existing value data. // The second is used if you want to open an existing value // and read it's data. The third is used if you just want to // make an object without doing any read/write of the data yet. // In all three cases, you can always use any of the Get/Set // operations on the object at a later time. // //-------------------------------------------------------------------------- class CRegBINARY : public CRegValue { public: // create/write value constructor CRegBINARY(const CRegKey &crkParent, const LPWSTR pwszValueID, const LPBYTE pbData, ULONG cbData); // io-less constructor - used by enumerator CRegBINARY(const CRegKey &crkParent, const LPWSTR pwszValueID); ~CRegBINARY(void){;}; DWORD SetBinary(const LPBYTE pbData, ULONG cbData); // Caller supplies buffer (supply the buffer size in bytes) DWORD GetBinary(LPBYTE pbData, ULONG *pcbData); DWORD GetTypeCode(void); DWORD QueryErrorStatus(void) { return _dwErr ; } private: DWORD _dwErr; }; //+------------------------------------------------------------------------- // // Member: CRegBINARY::CRegBINARY // // Purpose: Constructor for registry binary value // // History: 09/30/92 Rickhi Created // // Notes: // //-------------------------------------------------------------------------- inline CRegBINARY::CRegBINARY(const CRegKey &crkParent, const LPWSTR pwszValueID, const LPBYTE pbData, ULONG cbData) : CRegValue(crkParent, pwszValueID) { if (ERROR_SUCCESS == (_dwErr = CRegValue::QueryErrorStatus())) _dwErr = SetBinary(pbData, cbData); } inline CRegBINARY::CRegBINARY(const CRegKey &crkParent, const LPWSTR pwszValueID) : CRegValue(crkParent, pwszValueID) { // automatic actions in header are sufficient _dwErr = CRegValue::QueryErrorStatus(); } inline DWORD CRegBINARY::SetBinary(const LPBYTE pbData, ULONG cbData) { return SetValue(pbData, cbData, REG_BINARY); } inline DWORD CRegBINARY::GetBinary(LPBYTE pbData, ULONG* pcbData) { DWORD dwTypeCode; return GetValue(pbData, pcbData, &dwTypeCode); } inline DWORD CRegBINARY::GetTypeCode(void) { return REG_BINARY; } //+------------------------------------------------------------------------- // // Function: DelRegKeyTree // // Purpose: This function can be used to deleting a key and all it's // children. // // History: 09/30/93 AlokS Created // // Notes: We assume that caller has proper access priviledge // and the key is non-volatile. // //-------------------------------------------------------------------------- DWORD DelRegKeyTree ( HKEY hParent, LPWSTR lpwszKeyPath); #endif // __DSYSREG_HXX__