1

I was able to use Boost Iterator Facade to build a custom Single Pass Iterator to iterate (in a C++ way) through the values contained in a Windows registry key, wrapping the C API RegEnumValue.

E.g.:

// For each value 'v' under the given registry key 'hKey':
for (const auto& v : RegistryValueIterator(hKey)) 
{
    ...
}

Basically, the iterator's increment method calls RegEnumValue increasing the dwIndex parameter (initially set to 0 in the iterator class constructor), and when ERROR_NO_MORE_ITEMS is returned, that is mapped to the "end" iterator.

I've used the boost::single_pass_traversal_tag:

class RegistryValueIterator
    : public boost::iterator_facade< RegistryValueIterator,
                                     RegistryValueEntry,
                                     boost::single_pass_traversal_tag >
{
    ...

Boost.Filesystem's directory_iterator, which wraps the FindNextFile API in the Windows implementation, is implemented as a single-pass iterator, too. And similarly, the std::experimental::filesystem::directory_iterator is an Input Iterator as well (not a Forward Iterator).

So, would it be possible for registry enumeration to upgrade the iterator category to a Forward Traversal Iterator? What steps should I follow to achieve that goal?

In other words, would it be possible to implement a multi-pass traversal required by Forward Traversal Iterators using the Windows registry APIs like RegEnumValue? If so, how?


P.S. I've discussed registry value enumeration/iteration, but things are very similar for enumerating/iterating through registry keys as well, using the RegEnumKeyEx API.

Mr.C64
  • 41,637
  • 14
  • 86
  • 162
  • Have you tried specifying `forward_traversal_tag` instead of `single_pass_traversal_tag`? Did it work or not? What happened? I don't see anything in Boost's documentation that requires a "Forward Traversal" iterator to support "multi-pass traversal", only "single-pass traversal". You need to provide details of what you have already attempted, or else this is likely to get closed as off-topic asking for people's opinions instead of addressing technical facts. – Remy Lebeau Nov 30 '16 at 20:27
  • 1
    @RemyLebeau: Changing a tag isn't sufficient: you have to implement proper semantics. For ForwardIt being multi-pass vs. InputIt being single-pass read [this interesting answer](http://stackoverflow.com/a/6449296/1629821). Note also that with FwdIt (see 3rd § in that answer) there are more features than InIt, e.g. can have multiple usable copies of an iterator at once, etc. It's unclear to me how to make copies of iterators when using RegEnumValue. ... – Mr.C64 Nov 30 '16 at 23:47
  • ... I've already provided details of what I did in my question: it's precise and not off-topic at all. I also did a fair amount of research before posting. If you know technical facts to implement a FwdIt for registry enumeration then provide those. – Mr.C64 Nov 30 '16 at 23:48
  • 1
    You explained how you implemented a single-pass iterator, but not what you have attempted so far to implemented a forward-traversal iterator, or what research you have found that you do not understand how to implement. You just asked if it is possible, but nothing beyond that. In any case, to make a copy of a Registry enumeration, you can duplicate an open Registry key handle using `DuplicateHandle()`, copy the current index to another variable, and then you can enumerate the two handles independently of each other. – Remy Lebeau Dec 01 '16 at 00:58
  • @RemyLebeau: Thanks for the additional interesting information. Sounds like this is a path I can investigate. – Mr.C64 Dec 01 '16 at 10:48

0 Answers0