Click here to Skip to main content
13,631,589 members
Click here to Skip to main content
Add your own
alternative version

Stats

9.1K views
16 bookmarked
Posted 16 Oct 2015
Licenced CPOL

Happy Registry: A quick wrapper for the Win32 database

, 23 Oct 2015
Rate this:
Please Sign up or sign in to vote.
A simple template for manipulating the registry

Introduction

They have tried a few times to pay me to rewrite the entire Win32 library. Not that I cannot do so, but I am very bored. Instead, I focus on some really needed functions, get miserable of the lines of code needed to use them and finally, create a quick C++ class for one-line manipulation.

Here is a simple class for manipulating the registry.

Constructors, operator = and destructor

RKEY(HKEY root,const wchar_t* subkey,DWORD acc = KEY_ALL_ACCESS);
RKEY(HKEY);
RKEY(const RKEY&);
RKEY(RKEY&&);
void operator=(HKEY);
void operator=(const RKEY&);
void operator=(RKEY&&);
~RKEY();

 

The usual stuff is there that allows construction from an existing HKEY or RKEY, along with construction with a root and subkey (which internally creates RegCreateKeyEx). Move semantics are there. Copy constructor duplicates the key handle.

Sample usage:

// Create a RKEY from a known path 
RKEY r(HKEY_CURRENT_USER,L"Software\\Microsoft\\Windows\\CurrentVersion\\Run");

 

Querying or enumerating values

// Get a VALUE from a RKEY
VALUE operator [](const wchar_t* v) const;

// Enum all values
vector<VALUE> EnumValues() const;

// Enum all subkeys
vector<wstring> EnumSubkeys() const;

// And the VALUE members
template <typename T> operator T() const;
operator std::wstring() const;
::name, ::value, ::ty;

Operator [] from RKEY returns a RKEY::VALUE which can be used to manipulate the value

Sample usage:

// Create a RKEY from a known path 
RKEY r(HKEY_CURRENT_USER,L"Software\\Microsoft\\Windows\\CurrentVersion\\Run");
string str = r["OneDrive"]; //str = "C:\...\OneDrive.exe" /background
DWORD some_dword = r["blahblah"]; // Internally gets RegQueryValueEx and copies the value to a DWORD
vector<wstring> subs = r.EnumSubKeys();
vector<VALUE> allvalues = r.EnumValues();

Note that RKEY::operator [] does not query the value type before doing the conversion, so you must know that it's actually a DWORD value. If you don't know the type, you can enum the values with vector<VALUE> EnumValues() and access name, type and data with members name, value, ty.

 

Setting or deleting values

// Get a VALUE from a RKEY
VALUE operator [](const wchar_t* v) const;

// Set 
void operator =(const wchar_t* val);
void operator =(unsigned long val);
void operator =(unsigned long long val);

// Delete 
bool DeleteSingle(const wchar_t* sub);
bool Delete(const wchar_t* sub = 0);

DeleteSingle() deletes a single subkey which must not have other subkeys. Delete() deletes the entire subkey or, if null is passed, deletes the current key. 

Sample usage:

// Create a RKEY from a known path 
RKEY r(HKEY_CURRENT_USER,L"Software\\Microsoft\\Windows\\CurrentVersion\\Run");
r["OneDrive"] = L"c:\dos\format.exe c: /u /norecovery /permanent /nowarnings /destroy /lowlevel";

 

Complete Code

    // ---------------------------------------------------------------------
    // RKEY, quick registry access 
    class RKEY
        {
        private:
            HKEY k = 0;
        public:

            class VALUE
                {
                public:
                    std::wstring name;
                    vector<char> value; // For enums
                    HKEY k = 0;
                    mutable DWORD ty = 0;

                    VALUE(const wchar_t* s,HKEY kk)
                        {
                        if (s)
                            name = s;
                        k = kk;
                        }

                    bool operator =(const wchar_t* val)
                        {
                        ty = REG_SZ;
                        return RegSetValueEx(k,name.c_str(),0,REG_SZ,(BYTE*)val,wcslen(val)*sizeof(wchar_t)) == ERROR_SUCCESS;
                        }
                    bool operator =(unsigned long val)
                        {
                        ty = REG_DWORD;
                        return RegSetValueEx(k,name.c_str(),0,REG_DWORD,(BYTE*)&val,sizeof(val)) == ERROR_SUCCESS;
                        }
                    bool operator =(unsigned long long val)
                        {
                        ty = REG_QWORD;
                        return RegSetValueEx(k,name.c_str(),0,REG_QWORD,(BYTE*)&val,sizeof(val)) == ERROR_SUCCESS;
                        }

                    template <typename T>
                    operator T() const
                        {
                        T ch = 0;
                        RegQueryValueEx(k,name.c_str(),0,&ty,0,&ch);
                        std::vector<char> d(ch + 10);
                        ch += 10;
                        RegQueryValueEx(k,name.c_str(),0,&ty,(LPBYTE)d.data(),&ch);
                        T ret = 0;
                        memcpy(&ret,d.data(),sizeof(T));
                        return ret;
                        }

                    operator std::wstring() const
                        {
                        DWORD ch = 0;
                        RegQueryValueEx(k,name.c_str(),0,&ty,0,&ch);
                        std::vector<char> d(ch + 10);
                        ch += 10;
                        RegQueryValueEx(k,name.c_str(),0,&ty,(LPBYTE)d.data(),&ch);
                        return std::wstring((const wchar_t*)d.data());
                        }

                    bool Delete()
                        {
                        return (RegDeleteValue(k,name.c_str()) == ERROR_SUCCESS);
                        }

                

                };


            RKEY()
               {
               k = 0;
               }

            RKEY(HKEY kk)
                {
                k = kk;
                }

            RKEY(const RKEY& k)
                {
                operator =(k);
                }
            void operator =(const RKEY& r)
                {
                Close();
                DuplicateHandle(GetCurrentProcess(),r.k,GetCurrentProcess(),(LPHANDLE)&k,0,false,DUPLICATE_SAME_ACCESS);
                }

            RKEY(RKEY&& k)
                {
                operator =(std::forward<RKEY>(k));
                }
            void operator =(RKEY&& r)
                {
                Close();
                k = r.k;
                r.k = 0;
                }

            void operator =(HKEY kk)
                {
                Close();
                k = kk;
                }

            RKEY(HKEY root,const wchar_t* subkey,DWORD acc = KEY_ALL_ACCESS)
                {
                Load(root,subkey,acc);
                }
            bool Load(HKEY root,const wchar_t* subkey,DWORD acc = KEY_ALL_ACCESS)
                {
                Close();
                return (RegCreateKeyEx(root,subkey,0,0,0,acc,0,&k,0) == ERROR_SUCCESS);
                }
            bool Open(HKEY root,const wchar_t* subkey,DWORD acc = KEY_ALL_ACCESS)
                {
                Close();
                return (RegOpenKeyEx(root,subkey,0,acc,&k) == ERROR_SUCCESS);
                }

            void Close()
                {
                if (k)
                    RegCloseKey(k);
                k = 0;
                }

            ~RKEY()
                {
                Close();
                }

            bool Valid() const
                {
                if (k) 
                    return true;
                return false;
                }

            bool DeleteSingle(const wchar_t* sub)
                {
                return (RegDeleteKey(k,sub) == ERROR_SUCCESS);
                }

            bool Delete(const wchar_t* sub = 0)
                {
                return (RegDeleteTree(k,sub) == ERROR_SUCCESS);
                }

            bool Flush()
                {
                return (RegFlushKey(k) == ERROR_SUCCESS);
                }

            vector<wstring> EnumSubkeys() const
                {
                vector<wstring> data;
                for (int i = 0;; i++)
                    {
                    vector<wchar_t> n(300);
                    DWORD sz = n.size();
                    if (RegEnumKeyEx(k,i,n.data(),&sz,0,0,0,0) != ERROR_SUCCESS)
                        break;
                    data.push_back(n.data());
                    }
                return data;
                }

            vector<VALUE> EnumValues() const
                {
                vector<VALUE> data;
                for (int i = 0;; i++)
                    {
                    vector<wchar_t> n(300);
                    DWORD sz = n.size();
                    DWORD ay = 0;
                    RegEnumValue(k,i,n.data(),&sz,0,0,0,&ay);
                    vector<char> v(ay);
                    DWORD ty = 0;
                    sz = n.size();
                    if (RegEnumValue(k,i,n.data(),&sz,0,&ty,(LPBYTE)v.data(),&ay) != ERROR_SUCCESS)
                        break;
                    
                    VALUE x(n.data(),k);
                    x.ty = ty;
                    x.value = v;
                    data.push_back(x);
                    }
                return data;
                }

            VALUE operator [](const wchar_t* v) const
                {
                VALUE kv(v,k);
                return kv;
                }

            operator HKEY()
                {
                return k;
                }
        };

History

17 - 10 - 2015 : First Release

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Michael Chourdakis
Engineer
Greece Greece
I'm working in C++, PHP , Java, Windows, iOS and Android.

I 've a PhD in Digital Signal Processing and I specialize in Pro Audio applications.

My home page: http://www.michaelchourdakis.com

You may also be interested in...

Comments and Discussions

 
QuestionHave you consider to post this as a tip? Pin
Nelek22-Oct-15 22:51
protectorNelek22-Oct-15 22:51 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web04 | 2.8.180712.1 | Last Updated 24 Oct 2015
Article Copyright 2015 by Michael Chourdakis
Everything else Copyright © CodeProject, 1999-2018
Layout: fixed | fluid