Thread: Registry keys

  1. #1
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895

    Registry keys

    Given two HKEYs, original and copy, where copy is a copy of original obtained through RegOpenKeyEx by passing 0 as name, is there a way to find out if these two point to the same key?
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  2. #2
    Registered User
    Join Date
    Nov 2001
    Posts
    1,348
    Post a specific examples.

    Do you want to comparehandle, pointer, or the actual string of the registry key?

    Kuphryn

  3. #3
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    I don't think there is any reliable way to compare based on HKEY handles alone.

    gg

  4. #4
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Example. I have written an iterator over registry keys (Codeplug knows this).

    The iterator essentially looks like this:
    Code:
    class reg_key_iterator {
    	// Used for RegEnumKeysEx
    	HKEY parent;
    	DWORD index;
    
    public:
    	reg_key_iterator(HKEY p, DWORD i)
    		: index(i)
    	{
    		internal::regCopyKey(p, KEY_ALL_ACCESS, parent);
    	}
    }
    internal::regCopyKey just calls RegOpenKeyEx to copy the handle p into parent.
    Code:
    ::RegOpenKeyEx(in, 0, 0, sam, &out);
    The problem is, if I create two iterators over the same key with this, I need to compare them, and parent == o.parent doesn't work, because the handles have different values.
    The iterator copies the key to avoid other objects closing the handle.

    Is there a way I can find out if two HKEYs with distinct values point to the same key?

    Thx in advance.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  5. #5
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    I noticed on my win2k box that the first copied handle was only 4 bytes off from the original handle value - probably don't want to count on that though.

    First thing that comes to my mind is to keep track of the full "pathname" of the hive that reg_key_iterator is iterating over.

    Or you could come up with a HKEY class that uses reference counting so you don't have to make copies, then use the HKEY in the comparison.

    gg

  6. #6
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    I used the second solution. Is this shared_hkey correct?
    Code:
    class shared_hkey {
    	HKEY key;
    	long *refcount;
    public:
    	shared_hkey()
    		: key(0), refcount(0)
    	{
    	}
    	shared_hkey(HKEY h)
    		: key(h)
    	{
    		refcount = new long;
    		*refcount = 1;
    	}
    	shared_hkey(const shared_hkey &o)
    		: key(o.key), refcount(o.refcount)
    	{
    		if(refcount) {
    			++*refcount;
    		}
    	}
    	~shared_hkey() {
    		reset(0);
    	}
    	shared_hkey &operator =(const shared_hkey &o) {
    		if(o != *this) {
    			reset(0);
    			key = o.key;
    			refcount = o.refcount;
    			++*refcount;
    		}
    		return *this;
    	}
    	void reset(HKEY h) {
    		if(h != key && refcount) {
    			if(--*refcount == 0) {
    				delete refcount;
    				refcount = 0;
    				regCloseKey(key);
    				key = 0;
    			}
    		}
    		key = h;
    		if(key) {
    			refcount = new long;
    			*refcount = 1;
    		}
    	}
    	operator HKEY() const {
    		return key;
    	}
    	bool operator ==(const shared_hkey &o) {
    		return key == o.key;
    	}
    	bool operator !=(const shared_hkey &o) {
    		return key != o.key;
    	}
    };
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  7. #7
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    This will cause a memory leak:
    Code:
        shared_hkey sk;
        sk.reset((HKEY)5);
        sk.reset((HKEY)5);
    Code:
        void reset(HKEY h) {
            if(key != h) {
                // "detach" from our current key
                if(refcount && --*refcount == 0) {
                    delete refcount;
                    refcount = 0;
                    regCloseKey(key);
                }
                //not really needed, but don't get warm fuzzies seeing it there
                refcount = 0; 
                key = h;
                if(key) {
                    refcount = new long;
                    *refcount = 1;
                }
            }
        }//reset
    Some other recommendations:
    Code:
    bool operator ==(const shared_hkey &o) const {
    bool operator !=(const shared_hkey &o) const {
    Looks good.

    gg

  8. #8
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Thanks a lot. Works like a charm.

    Now I need to get my dialog stream buffer properly working, but that's another project
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. help with registry keys
    By Anubis208 in forum Windows Programming
    Replies: 5
    Last Post: 05-24-2008, 09:11 AM
  2. Registry Keys
    By cgod in forum Windows Programming
    Replies: 3
    Last Post: 11-12-2004, 05:12 AM
  3. Registry Keys in C++
    By Apoc in forum Windows Programming
    Replies: 1
    Last Post: 08-21-2004, 09:46 PM
  4. Recusively delete registry keys
    By SMurf in forum Windows Programming
    Replies: 4
    Last Post: 01-22-2004, 11:24 PM
  5. Interesting Registry Stuff (Keys, Values, etc.)
    By civix in forum A Brief History of Cprogramming.com
    Replies: 9
    Last Post: 01-27-2003, 09:58 AM