00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00057 #ifndef WINSTL_INCL_WINSTL_REGISTRY_HPP_REG_KEY_SEQUENCE
00058 #define WINSTL_INCL_WINSTL_REGISTRY_HPP_REG_KEY_SEQUENCE
00059
00060 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00061 # define WINSTL_VER_WINSTL_REGISTRY_HPP_REG_KEY_SEQUENCE_MAJOR 3
00062 # define WINSTL_VER_WINSTL_REGISTRY_HPP_REG_KEY_SEQUENCE_MINOR 9
00063 # define WINSTL_VER_WINSTL_REGISTRY_HPP_REG_KEY_SEQUENCE_REVISION 1
00064 # define WINSTL_VER_WINSTL_REGISTRY_HPP_REG_KEY_SEQUENCE_EDIT 131
00065 #endif
00066
00067
00068
00069
00070
00071 #ifndef WINSTL_INCL_WINSTL_H_WINSTL
00072 # include <winstl/winstl.h>
00073 #endif
00074 #ifndef WINSTL_INCL_WINSTL_REGISTRY_HPP_REGFWD
00075 # include <winstl/registry/regfwd.hpp>
00076 #endif
00077 #ifndef WINSTL_INCL_WINSTL_REGISTRY_UTIL_HPP_DEFS
00078 # include <winstl/registry/util/defs.hpp>
00079 #endif
00080 #ifndef WINSTL_INCL_WINSTL_REGISTRY_HPP_REG_TRAITS
00081 # include <winstl/registry/reg_traits.hpp>
00082 #endif
00083 #ifndef WINSTL_INCL_WINSTL_REGISTRY_HPP_REG_KEY
00084 # include <winstl/registry/reg_key.hpp>
00085 #endif
00086 #ifndef WINSTL_INCL_WINSTL_REGISTRY_UTIL_HPP_SHARED_HANDLES
00087 # include <winstl/registry/util/shared_handles.hpp>
00088 #endif
00089 #ifndef STLSOFT_INCL_STLSOFT_MEMORY_HPP_AUTO_BUFFER
00090 # include <stlsoft/memory/auto_buffer.hpp>
00091 #endif
00092 #ifndef WINSTL_INCL_WINSTL_MEMORY_HPP_PROCESSHEAP_ALLOCATOR
00093 # include <winstl/memory/processheap_allocator.hpp>
00094 #endif
00095 #ifndef STLSOFT_INCL_STLSOFT_UTIL_STD_HPP_ITERATOR_HELPER
00096 # include <stlsoft/util/std/iterator_helper.hpp>
00097 #endif
00098 #ifndef STLSOFT_INCL_STLSOFT_COLLECTIONS_UTIL_HPP_COLLECTIONS
00099 # include <stlsoft/collections/util/collections.hpp>
00100 #endif
00101 #ifndef STLSOFT_INCL_STLSOFT_SMARTPTR_HPP_REF_PTR
00102 # include <stlsoft/smartptr/ref_ptr.hpp>
00103 #endif
00104 #ifndef STLSOFT_INCL_STLSOFT_SMARTPTR_HPP_SCOPED_HANDLE
00105 # include <stlsoft/smartptr/scoped_handle.hpp>
00106 #endif
00107
00108
00109
00110
00111
00112 #ifndef _WINSTL_NO_NAMESPACE
00113 # if defined(_STLSOFT_NO_NAMESPACE) || \
00114 defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00115
00116 namespace winstl
00117 {
00118 # else
00119
00120
00121 namespace stlsoft
00122 {
00123
00124 namespace winstl_project
00125 {
00126
00127 # endif
00128 #endif
00129
00130
00131
00132
00141 template< ss_typename_param_k C
00142 #ifdef STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT
00143 , ss_typename_param_k T = reg_traits<C>
00144 , ss_typename_param_k A = processheap_allocator<C>
00145 #else
00146 , ss_typename_param_k T
00147 , ss_typename_param_k A
00148 #endif
00149 >
00150 class basic_reg_key_sequence
00151 : public stlsoft_ns_qual(stl_collection_tag)
00152 {
00155 public:
00157 typedef C char_type;
00159 typedef T traits_type;
00161 typedef A allocator_type;
00163 typedef basic_reg_key_sequence<C, T, A> class_type;
00165 typedef basic_reg_key<C, T, A> key_type;
00167 typedef key_type value_type;
00169 typedef ss_typename_type_k traits_type::size_type size_type;
00171 typedef basic_reg_key<C, T, A> reg_key_type;
00173 typedef basic_reg_key_sequence_iterator<C, T, value_type, A> iterator;
00177 typedef iterator const_iterator;
00179 typedef key_type& reference;
00181 typedef key_type const& const_reference;
00183 #if defined(STLSOFT_COMPILER_IS_MSVC) && \
00184 _MSC_VER == 1100
00185
00186 typedef HKEY hkey_type;
00187 #else
00188 typedef ss_typename_type_k traits_type::hkey_type hkey_type;
00189 #endif
00191 typedef ws_ptrdiff_t difference_type;
00193 #if defined(STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT)
00194 typedef stlsoft_ns_qual(reverse_bidirectional_iterator_base) < iterator
00195 , value_type
00196 , value_type
00197 , void
00198 , difference_type
00199 > reverse_iterator;
00200 #endif
00202 typedef ws_bool_t bool_type;
00203 private:
00205 typedef ss_typename_type_k traits_type::result_type result_type;
00206 private:
00207 typedef stlsoft_ns_qual(auto_buffer_old)< char_type
00208 , allocator_type
00209 , CCH_REG_API_AUTO_BUFFER
00210 > buffer_type_;
00211 public:
00212 typedef hkey_type resource_type;
00214
00217 public:
00227 basic_reg_key_sequence( hkey_type hkey
00228 , char_type const *sub_key_name
00229 , REGSAM accessMask = KEY_READ);
00241 basic_reg_key_sequence( hkey_type hkey
00242 , char_type const *sub_key_name
00243 , REGSAM accessMask
00244 , bool_type bMonitorExternalInvalidation);
00251 ss_explicit_k basic_reg_key_sequence(reg_key_type const& key);
00259 basic_reg_key_sequence( reg_key_type const &key
00260 , REGSAM accessMask);
00270 basic_reg_key_sequence( reg_key_type const &key
00271 , REGSAM accessMask
00272 , bool_type bMonitorExternalInvalidation);
00274 ~basic_reg_key_sequence() stlsoft_throw_0();
00276
00279 public:
00283 iterator begin();
00287 iterator end();
00288
00289 #if defined(STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT)
00293 reverse_iterator rbegin();
00297 reverse_iterator rend();
00298 #endif
00300
00303 public:
00308 size_type current_size() const;
00312 size_type size() const;
00314 ws_bool_t empty() const;
00315
00317 hkey_type get_key_handle() const;
00319 hkey_type get() const;
00321
00324 private:
00325 registry_util::shared_handle *create_shared_handle_(result_type &res);
00326 static REGSAM validate_access_mask_(REGSAM accessMask, bool_type bMonitorExternalInvalidation);
00327 static hkey_type dup_key_(hkey_type hkey, REGSAM accessMask);
00329
00332 private:
00333 hkey_type m_hkey;
00334 const REGSAM m_accessMask;
00335 const bool_type m_bMonitorExternalInvalidation;
00337
00340 private:
00341 basic_reg_key_sequence(class_type const&);
00342 class_type& operator =(class_type const&);
00344 };
00345
00346
00351 typedef basic_reg_key_sequence<ws_char_a_t, reg_traits<ws_char_a_t>, processheap_allocator<ws_char_a_t> > reg_key_sequence_a;
00356 typedef basic_reg_key_sequence<ws_char_w_t, reg_traits<ws_char_w_t>, processheap_allocator<ws_char_w_t> > reg_key_sequence_w;
00361 typedef basic_reg_key_sequence<TCHAR, reg_traits<TCHAR>, processheap_allocator<TCHAR> > reg_key_sequence;
00362
00363
00373 template< ss_typename_param_k C
00374 , ss_typename_param_k T
00375 , ss_typename_param_k V
00376 , ss_typename_param_k A
00377 >
00378 class basic_reg_key_sequence_iterator
00379 : public stlsoft_ns_qual(iterator_base)<winstl_ns_qual_std(bidirectional_iterator_tag)
00380 , V
00381 , ws_ptrdiff_t
00382 , void
00383 , V
00384 >
00385 {
00388 public:
00390 typedef C char_type;
00392 typedef T traits_type;
00394 typedef V value_type;
00396 typedef A allocator_type;
00398 typedef basic_reg_key_sequence_iterator<C, T, V, A> class_type;
00400 typedef ss_typename_type_k traits_type::size_type size_type;
00402 typedef ss_typename_type_k traits_type::difference_type difference_type;
00404 typedef ss_typename_type_k traits_type::string_type string_type;
00406 typedef ws_sint32_t index_type;
00408 typedef ss_typename_type_k traits_type::hkey_type hkey_type;
00409 private:
00411 typedef ss_typename_type_k traits_type::result_type result_type;
00413 typedef ws_bool_t bool_type;
00414 private:
00415 typedef stlsoft_ns_qual(auto_buffer_old)< char_type
00416 , allocator_type
00417 , CCH_REG_API_AUTO_BUFFER
00418 > buffer_type_;
00420
00423 private:
00424 friend class basic_reg_key_sequence<C, T, A>;
00425
00427 basic_reg_key_sequence_iterator(registry_util::shared_handle *handle, char_type const* name, size_type cchName, index_type index, REGSAM accessMask)
00428 : m_handle(handle)
00429 , m_index(index)
00430 , m_name(name, cchName)
00431 , m_accessMask(accessMask)
00432 {
00433 WINSTL_ASSERT(NULL != m_handle);
00434 m_handle->test_reset_and_throw();
00435 m_handle->AddRef();
00436 }
00437 public:
00439 basic_reg_key_sequence_iterator();
00441 basic_reg_key_sequence_iterator(class_type const& rhs);
00443 ~basic_reg_key_sequence_iterator() stlsoft_throw_0();
00444
00446 class_type& operator =(class_type const& rhs);
00448
00451 public:
00452 string_type const &get_key_name() const;
00454
00457 public:
00459 class_type& operator ++();
00461 class_type& operator --();
00463 const class_type operator ++(int);
00465 const class_type operator --(int);
00467 const value_type operator *() const;
00469 ws_bool_t equal(class_type const& rhs) const;
00471 ws_bool_t operator ==(class_type const& rhs) const;
00473 ws_bool_t operator !=(class_type const& rhs) const;
00475
00478 private:
00479 static index_type sentinel_() stlsoft_throw_0();
00481
00484 private:
00485 registry_util::shared_handle *m_handle;
00486 index_type m_index;
00487 string_type m_name;
00488 REGSAM m_accessMask;
00490 };
00491
00493
00494
00495 #ifdef STLSOFT_UNITTEST
00496 # include "./unittest/reg_key_sequence_unittest_.h"
00497 #endif
00498
00500
00501
00502 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00503
00504
00505
00506 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
00507 inline registry_util::shared_handle *basic_reg_key_sequence<C, T, A>::create_shared_handle_(result_type &res)
00508 {
00509
00510
00511
00512
00513 hkey_type hkey2 = traits_type::key_dup(m_hkey, m_accessMask, &res);
00514
00515 if(NULL == hkey2)
00516 {
00517 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00518 static const char message[] = "could not duplicate key";
00519
00520 if(ERROR_ACCESS_DENIED == res)
00521 {
00522 STLSOFT_THROW_X(access_denied_exception(message, res));
00523 }
00524 else
00525 {
00526 STLSOFT_THROW_X(key_not_duplicated_exception(message, res));
00527 }
00528 #else
00529 ;
00530 #endif
00531 }
00532 else
00533 {
00534
00535 scoped_handle<HKEY> sh(hkey2, ::RegCloseKey);
00536 registry_util::shared_handle *handle = registry_util::create_shared_handle(hkey2, m_bMonitorExternalInvalidation, REG_NOTIFY_CHANGE_NAME);
00537
00538 if(NULL == handle)
00539 {
00540 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00541 static const char message[] = "could not create shared enumeration context";
00542 DWORD err = ::GetLastError();
00543
00544 if(ERROR_ACCESS_DENIED == err)
00545 {
00546 STLSOFT_THROW_X(access_denied_exception(message, err));
00547 }
00548 else
00549 {
00550 STLSOFT_THROW_X(registry_exception(message, err));
00551 }
00552 #else
00553 ;
00554 #endif
00555 }
00556 else
00557 {
00558 sh.detach();
00559
00560 return handle;
00561 }
00562 }
00563
00564 return NULL;
00565 }
00566
00567 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
00568 inline REGSAM basic_reg_key_sequence<C, T, A>::validate_access_mask_(REGSAM accessMask, ss_typename_type_k basic_reg_key_sequence<C, T, A>::bool_type bMonitorExternalInvalidation)
00569 {
00570 if(bMonitorExternalInvalidation)
00571 {
00572 return accessMask | KEY_NOTIFY;
00573 }
00574 else
00575 {
00576 return accessMask & ~(KEY_NOTIFY);
00577 }
00578 }
00579
00580 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
00581 inline ss_typename_type_ret_k basic_reg_key_sequence<C, T, A>::hkey_type basic_reg_key_sequence<C, T, A>::dup_key_(ss_typename_type_k basic_reg_key_sequence<C, T, A>::hkey_type hkey, REGSAM accessMask)
00582 {
00583 result_type res;
00584 HKEY hkeyDup = traits_type::key_dup(hkey, accessMask, &res);
00585
00586 if(ERROR_SUCCESS != res)
00587 {
00588 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00589 static const char message[] = "could not duplicate key";
00590
00591 if(ERROR_ACCESS_DENIED == res)
00592 {
00593 STLSOFT_THROW_X(access_denied_exception(message, res));
00594 }
00595 else
00596 {
00597 STLSOFT_THROW_X(key_not_duplicated_exception(message, res));
00598 }
00599 #else
00600 hkeyDup = NULL;
00601 #endif
00602 }
00603
00604 return hkeyDup;
00605 }
00606
00607 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
00608 inline basic_reg_key_sequence<C, T, A>::basic_reg_key_sequence( ss_typename_type_k basic_reg_key_sequence<C, T, A>::hkey_type hkey
00609 , ss_typename_type_k basic_reg_key_sequence<C, T, A>::char_type const* sub_key_name
00610 , REGSAM accessMask )
00611 : m_hkey(NULL)
00612 , m_accessMask(accessMask)
00613 , m_bMonitorExternalInvalidation(0 != (KEY_NOTIFY & accessMask))
00614 {
00615 result_type res;
00616
00617 if(ERROR_SUCCESS != (res = traits_type::reg_open_key(hkey, sub_key_name, &m_hkey, accessMask)))
00618 {
00619 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00620 static const char message[] = "could not open key";
00621
00622 if(ERROR_ACCESS_DENIED == res)
00623 {
00624 STLSOFT_THROW_X(access_denied_exception(message, res));
00625 }
00626 else
00627 {
00628 STLSOFT_THROW_X(registry_exception(message, res));
00629 }
00630 #else
00631 m_hkey = NULL;
00632 #endif
00633 }
00634 }
00635
00636 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
00637 inline basic_reg_key_sequence<C, T, A>::basic_reg_key_sequence( ss_typename_type_k basic_reg_key_sequence<C, T, A>::hkey_type hkey
00638 , ss_typename_type_k basic_reg_key_sequence<C, T, A>::char_type const* sub_key_name
00639 , REGSAM accessMask
00640 , ss_typename_type_k basic_reg_key_sequence<C, T, A>::bool_type bMonitorExternalInvalidation)
00641 : m_hkey(NULL)
00642 , m_accessMask(validate_access_mask_(accessMask, bMonitorExternalInvalidation))
00643 , m_bMonitorExternalInvalidation(bMonitorExternalInvalidation)
00644 {
00645 result_type res;
00646
00647 if(ERROR_SUCCESS != (res = traits_type::reg_open_key(hkey, sub_key_name, &m_hkey, accessMask)))
00648 {
00649 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00650 static const char message[] = "could not open key";
00651
00652 if(ERROR_ACCESS_DENIED == res)
00653 {
00654 STLSOFT_THROW_X(access_denied_exception(message, res));
00655 }
00656 else
00657 {
00658 STLSOFT_THROW_X(registry_exception(message, res));
00659 }
00660 #else
00661 m_hkey = NULL;
00662 #endif
00663 }
00664 }
00665
00666 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
00667 inline basic_reg_key_sequence<C, T, A>::basic_reg_key_sequence(ss_typename_type_k basic_reg_key_sequence<C, T, A>::reg_key_type const& key)
00668 : m_hkey(dup_key_(key.m_hkey, key.get_access_mask()))
00669 , m_accessMask(key.get_access_mask())
00670 , m_bMonitorExternalInvalidation(0 != (KEY_NOTIFY & key.get_access_mask()))
00671 {
00672 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00673 if(NULL == m_hkey)
00674 {
00675 STLSOFT_THROW_X(registry_exception("Failed to take duplicate of key", ::GetLastError()));
00676 }
00677 #endif
00678 }
00679
00680 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
00681 inline basic_reg_key_sequence<C, T, A>::basic_reg_key_sequence( ss_typename_type_k basic_reg_key_sequence<C, T, A>::reg_key_type const &key
00682 , REGSAM accessMask)
00683 : m_hkey(dup_key_(key.m_hkey, accessMask))
00684 , m_accessMask(accessMask)
00685 , m_bMonitorExternalInvalidation(0 != (KEY_NOTIFY & accessMask))
00686 {
00687 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00688 if(NULL == m_hkey)
00689 {
00690 STLSOFT_THROW_X(registry_exception("Failed to take duplicate of key", ::GetLastError()));
00691 }
00692 #endif
00693 }
00694
00695 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
00696 inline basic_reg_key_sequence<C, T, A>::basic_reg_key_sequence( ss_typename_type_k basic_reg_key_sequence<C, T, A>::reg_key_type const &key
00697 , REGSAM accessMask
00698 , bool_type bMonitorExternalInvalidation)
00699 : m_hkey(dup_key_(key.m_hkey, validate_access_mask_(accessMask, bMonitorExternalInvalidation)))
00700 , m_accessMask(validate_access_mask_(accessMask, bMonitorExternalInvalidation))
00701 , m_bMonitorExternalInvalidation(bMonitorExternalInvalidation)
00702 {
00703 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00704 if(NULL == m_hkey)
00705 {
00706 STLSOFT_THROW_X(registry_exception("Failed to take duplicate of key", ::GetLastError()));
00707 }
00708 #endif
00709 }
00710
00711 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
00712 inline basic_reg_key_sequence<C, T, A>::~basic_reg_key_sequence() stlsoft_throw_0()
00713 {
00714 if(m_hkey != NULL)
00715 {
00716 ::RegCloseKey(m_hkey);
00717 }
00718 }
00719
00720 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
00721 inline ss_typename_type_ret_k basic_reg_key_sequence<C, T, A>::iterator basic_reg_key_sequence<C, T, A>::begin()
00722 {
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735 size_type cchName = 0;
00736 ws_uint32_t numEntries = 0;
00737 result_type res = traits_type::reg_query_info(m_hkey, NULL, NULL, &numEntries, &cchName, NULL, NULL, NULL, NULL, NULL, NULL);
00738
00739 if(ERROR_SUCCESS != res)
00740 {
00741 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00742 static const char message[] = "could not elicit sub-key information";
00743
00744 if(ERROR_ACCESS_DENIED == res)
00745 {
00746 STLSOFT_THROW_X(access_denied_exception(message, res));
00747 }
00748 else
00749 {
00750 STLSOFT_THROW_X(registry_exception(message, res));
00751 }
00752 #else
00753 ;
00754 #endif
00755 }
00756 else
00757 {
00758 if(0 != numEntries)
00759 {
00760
00761 registry_util::shared_handle *handle = create_shared_handle_(res);
00762 ws_sint32_t index = 0;
00763
00764 if(NULL == handle)
00765 {
00766 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00767 static const char message[] = "could not create shared enumeration context";
00768
00769 if(ERROR_ACCESS_DENIED == res)
00770 {
00771 STLSOFT_THROW_X(access_denied_exception(message, res));
00772 }
00773 else
00774 {
00775 STLSOFT_THROW_X(registry_exception(message, res));
00776 }
00777 #else
00778 ;
00779 #endif
00780 }
00781 else
00782 {
00783 ref_ptr<registry_util::shared_handle> ref(handle, false);
00784
00785
00786 buffer_type_ buffer(++cchName);
00787
00788 for(; !buffer.empty(); )
00789 {
00790 cchName = buffer.size();
00791
00792 res = traits_type::reg_enum_key(m_hkey, 0, &buffer[0], &cchName);
00793
00794 if(ERROR_MORE_DATA == res)
00795 {
00796 if(!buffer.resize(2 * buffer.size()))
00797 {
00798 cchName = 0;
00799 index = const_iterator::sentinel_();
00800 break;
00801 }
00802
00803 continue;
00804 }
00805 else if(ERROR_SUCCESS != res)
00806 {
00807 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00808 static const char message[] = "could not enumerate sub-keys";
00809
00810 if(ERROR_ACCESS_DENIED == res)
00811 {
00812 STLSOFT_THROW_X(access_denied_exception(message, res));
00813 }
00814 else
00815 {
00816 STLSOFT_THROW_X(registry_exception(message, res));
00817 }
00818 #else
00819 cchName = 0;
00820 index = const_iterator::sentinel_();
00821 break;
00822 #endif
00823 }
00824 else
00825 {
00826 break;
00827 }
00828 }
00829
00830
00831 return iterator(handle, buffer.data(), cchName, index, m_accessMask);
00832 }
00833 }
00834 }
00835
00836 return end();
00837 }
00838
00839 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
00840 inline ss_typename_type_ret_k basic_reg_key_sequence<C, T, A>::iterator basic_reg_key_sequence<C, T, A>::end()
00841 {
00842 result_type res;
00843 registry_util::shared_handle *handle = create_shared_handle_(res);
00844 ref_ptr<registry_util::shared_handle> ref(handle, false);
00845 ws_sint32_t index = const_iterator::sentinel_();
00846
00847 if(NULL == handle)
00848 {
00849 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00850 STLSOFT_THROW_X(registry_exception("Failed to take duplicate of key", res));
00851 #else
00852 index = 0;
00853 #endif
00854 }
00855
00856 return iterator(handle, NULL, 0, index, m_accessMask);
00857 }
00858
00859 #if defined(STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT)
00860 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
00861 inline ss_typename_type_ret_k basic_reg_key_sequence<C, T, A>::reverse_iterator basic_reg_key_sequence<C, T, A>::rbegin()
00862 {
00863 return reverse_iterator(end());
00864 }
00865
00866 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
00867 inline ss_typename_type_ret_k basic_reg_key_sequence<C, T, A>::reverse_iterator basic_reg_key_sequence<C, T, A>::rend()
00868 {
00869 return reverse_iterator(begin());
00870 }
00871 #endif
00872
00873 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
00874 inline ss_typename_type_ret_k basic_reg_key_sequence<C, T, A>::size_type basic_reg_key_sequence<C, T, A>::size() const
00875 {
00876 return current_size();
00877 }
00878
00879 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
00880 inline ss_typename_type_ret_k basic_reg_key_sequence<C, T, A>::size_type basic_reg_key_sequence<C, T, A>::current_size() const
00881 {
00882 ws_uint32_t numEntries;
00883 result_type res = traits_type::reg_query_info(m_hkey, NULL, NULL, &numEntries, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
00884
00885 if(ERROR_SUCCESS != res)
00886 {
00887 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00888 static const char message[] = "could not elicit number of sub-keys";
00889
00890 if(ERROR_ACCESS_DENIED == res)
00891 {
00892 STLSOFT_THROW_X(access_denied_exception(message, res));
00893 }
00894 else
00895 {
00896 STLSOFT_THROW_X(registry_exception(message, res));
00897 }
00898 #else
00899 numEntries = 0;
00900 #endif
00901 }
00902
00903 return static_cast<size_type>(numEntries);
00904 }
00905
00906 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
00907 inline ws_bool_t basic_reg_key_sequence<C, T, A>::empty() const
00908 {
00909 return 0 == size();
00910 }
00911
00912 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
00913 inline ss_typename_type_ret_k basic_reg_key_sequence<C, T, A>::hkey_type basic_reg_key_sequence<C, T, A>::get_key_handle() const
00914 {
00915 return m_hkey;
00916 }
00917
00918 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
00919 inline ss_typename_type_ret_k basic_reg_key_sequence<C, T, A>::hkey_type basic_reg_key_sequence<C, T, A>::get() const
00920 {
00921 return get_key_handle();
00922 }
00923
00924
00925
00926
00927 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V, ss_typename_param_k A>
00928 inline ss_typename_type_ret_k basic_reg_key_sequence_iterator<C, T, V, A>::index_type basic_reg_key_sequence_iterator<C, T, V, A>::sentinel_() stlsoft_throw_0()
00929 {
00930 return 0x7fffffff;
00931 }
00932
00933 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V, ss_typename_param_k A>
00934 inline basic_reg_key_sequence_iterator<C, T, V, A>::basic_reg_key_sequence_iterator()
00935 : m_handle(NULL)
00936 , m_index(sentinel_())
00937 , m_name()
00938 , m_accessMask(KEY_READ)
00939 {}
00940
00941 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V, ss_typename_param_k A>
00942 inline basic_reg_key_sequence_iterator<C, T, V, A>::basic_reg_key_sequence_iterator(class_type const& rhs)
00943 : m_handle(rhs.m_handle)
00944 , m_index(rhs.m_index)
00945 , m_name(rhs.m_name)
00946 , m_accessMask(rhs.m_accessMask)
00947 {
00948 if(NULL != m_handle)
00949 {
00950 m_handle->AddRef();
00951 }
00952 }
00953
00954 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V, ss_typename_param_k A>
00955 inline ss_typename_type_ret_k basic_reg_key_sequence_iterator<C, T, V, A>::class_type& basic_reg_key_sequence_iterator<C, T, V, A>::operator =(ss_typename_type_k basic_reg_key_sequence_iterator<C, T, V, A>::class_type const& rhs)
00956 {
00957 registry_util::shared_handle *this_handle;
00958
00959 m_index = rhs.m_index;
00960 m_name = rhs.m_name;
00961
00962 this_handle = m_handle;
00963 m_handle = rhs.m_handle;
00964 m_accessMask = rhs.m_accessMask;
00965
00966 if(NULL != m_handle)
00967 {
00968 m_handle->AddRef();
00969 }
00970
00971 if(NULL != this_handle)
00972 {
00973 this_handle->Release();
00974 }
00975
00976 return *this;
00977 }
00978
00979 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V, ss_typename_param_k A>
00980 inline basic_reg_key_sequence_iterator<C, T, V, A>::~basic_reg_key_sequence_iterator() stlsoft_throw_0()
00981 {
00982 if(NULL != m_handle)
00983 {
00984 m_handle->Release();
00985 }
00986 }
00987
00988 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V, ss_typename_param_k A>
00989 inline const ss_typename_type_k basic_reg_key_sequence_iterator<C, T, V, A>::string_type &basic_reg_key_sequence_iterator<C, T, V, A>::get_key_name() const
00990 {
00991 return m_name;
00992 }
00993
00994 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V, ss_typename_param_k A>
00995 inline ss_typename_type_ret_k basic_reg_key_sequence_iterator<C, T, V, A>::class_type& basic_reg_key_sequence_iterator<C, T, V, A>::operator ++()
00996 {
00997 WINSTL_MESSAGE_ASSERT("Attempting to increment an invalid iterator!", NULL != m_handle);
00998 WINSTL_MESSAGE_ASSERT("Attempting to increment an invalid iterator!", sentinel_() != m_index);
00999
01000
01001 size_type cchName = 0;
01002 result_type res = traits_type::reg_query_info(m_handle->m_hkey, NULL, NULL, NULL, &cchName, NULL, NULL, NULL, NULL, NULL, NULL);
01003
01004 if(ERROR_SUCCESS != res)
01005 {
01006 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
01007 static const char message[] = "could not elicit sub-key information";
01008
01009 if(ERROR_ACCESS_DENIED == res)
01010 {
01011 STLSOFT_THROW_X(access_denied_exception(message, res));
01012 }
01013 else
01014 {
01015 STLSOFT_THROW_X(registry_exception(message, res));
01016 }
01017 #else
01018 m_index = sentinel_();
01019 #endif
01020 }
01021 else
01022 {
01023 buffer_type_ buffer(++cchName);
01024
01025 for(; !buffer.empty(); buffer.resize(2 * buffer.size()))
01026 {
01027 cchName = buffer.size();
01028
01029 res = traits_type::reg_enum_key(m_handle->m_hkey, static_cast<ws_dword_t>(1 + m_index), &buffer[0], &cchName);
01030
01031 if(ERROR_MORE_DATA == res)
01032 {
01033 continue;
01034 }
01035 else if(ERROR_NO_MORE_ITEMS == res)
01036 {
01037 m_index = sentinel_();
01038 break;
01039 }
01040 else if(ERROR_SUCCESS != res)
01041 {
01042 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
01043 static const char message[] = "could not enumerate sub-keys";
01044
01045 if(ERROR_ACCESS_DENIED == res)
01046 {
01047 STLSOFT_THROW_X(access_denied_exception(message, res));
01048 }
01049 else
01050 {
01051 STLSOFT_THROW_X(registry_exception(message, res));
01052 }
01053 #else
01054 m_index = sentinel_();
01055 break;
01056 #endif
01057 }
01058 else
01059 {
01060 m_name.assign(buffer.data(), cchName);
01061
01062 ++m_index;
01063
01064 break;
01065 }
01066 }
01067 }
01068
01069 m_handle->test_reset_and_throw();
01070
01071 return *this;
01072 }
01073
01074 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V, ss_typename_param_k A>
01075 inline ss_typename_type_ret_k basic_reg_key_sequence_iterator<C, T, V, A>::class_type& basic_reg_key_sequence_iterator<C, T, V, A>::operator --()
01076 {
01077 WINSTL_MESSAGE_ASSERT("Attempting to decrement an invalid iterator", NULL != m_handle);
01078
01079
01080 size_type cchName = 0;
01081 ws_uint32_t numEntries = 0;
01082 result_type res = traits_type::reg_query_info(m_handle->m_hkey, NULL, NULL, &numEntries, &cchName, NULL, NULL, NULL, NULL, NULL, NULL);
01083
01084 if(ERROR_SUCCESS != res)
01085 {
01086 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
01087 static const char message[] = "could not elicit sub-key information";
01088
01089 if(ERROR_ACCESS_DENIED == res)
01090 {
01091 STLSOFT_THROW_X(access_denied_exception(message, res));
01092 }
01093 else
01094 {
01095 STLSOFT_THROW_X(registry_exception(message, res));
01096 }
01097 #else
01098 m_index = sentinel_();
01099 #endif
01100 }
01101 else
01102 {
01103 buffer_type_ buffer(++cchName);
01104 ws_dword_t index;
01105
01106
01107 if(m_index == sentinel_())
01108 {
01109
01110 index = numEntries - 1;
01111 }
01112 else
01113 {
01114
01115 index = m_index - 1;
01116 }
01117
01118 for(; !buffer.empty(); buffer.resize(2 * buffer.size()))
01119 {
01120 cchName = buffer.size();
01121
01122 res = traits_type::reg_enum_key(m_handle->m_hkey, index, &buffer[0], &cchName);
01123
01124 if(ERROR_MORE_DATA == res)
01125 {
01126 continue;
01127 }
01128 else if(ERROR_SUCCESS != res)
01129 {
01130 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
01131 static const char message[] = "could not elicit sub-key information";
01132
01133 if(ERROR_ACCESS_DENIED == res)
01134 {
01135 STLSOFT_THROW_X(access_denied_exception(message, res));
01136 }
01137 else
01138 {
01139 STLSOFT_THROW_X(registry_exception(message, res));
01140 }
01141 #else
01142 m_index = sentinel_();
01143 #endif
01144 }
01145 else
01146 {
01147 m_name.assign(buffer.data(), cchName);
01148
01149 m_index = index;
01150
01151 break;
01152 }
01153 }
01154 }
01155
01156 m_handle->test_reset_and_throw();
01157
01158 return *this;
01159 }
01160
01161 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V, ss_typename_param_k A>
01162 inline const ss_typename_type_k basic_reg_key_sequence_iterator<C, T, V, A>::class_type basic_reg_key_sequence_iterator<C, T, V, A>::operator ++(int)
01163 {
01164 class_type ret(*this);
01165
01166 operator ++();
01167
01168 return ret;
01169 }
01170
01171 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V, ss_typename_param_k A>
01172 inline const ss_typename_type_k basic_reg_key_sequence_iterator<C, T, V, A>::class_type basic_reg_key_sequence_iterator<C, T, V, A>::operator --(int)
01173 {
01174 class_type ret(*this);
01175
01176 operator --();
01177
01178 return ret;
01179 }
01180
01181 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V, ss_typename_param_k A>
01182 inline const ss_typename_type_k basic_reg_key_sequence_iterator<C, T, V, A>::value_type basic_reg_key_sequence_iterator<C, T, V, A>::operator *() const
01183 {
01184 WINSTL_MESSAGE_ASSERT("Attempting to dereference an invalid iterator", NULL != m_handle);
01185
01186 m_handle->test_reset_and_throw();
01187
01188 return value_type(m_handle->m_hkey, m_name, m_accessMask);
01189 }
01190
01191 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V, ss_typename_param_k A>
01192 inline ws_bool_t basic_reg_key_sequence_iterator<C, T, V, A>::equal(class_type const& rhs) const
01193 {
01194 return m_index == rhs.m_index;
01195 }
01196
01197 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V, ss_typename_param_k A>
01198 inline ws_bool_t basic_reg_key_sequence_iterator<C, T, V, A>::operator ==(class_type const& rhs) const
01199 {
01200 return equal(rhs);
01201 }
01202
01203 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V, ss_typename_param_k A>
01204 inline ws_bool_t basic_reg_key_sequence_iterator<C, T, V, A>::operator !=(class_type const& rhs) const
01205 {
01206 return !equal(rhs);
01207 }
01208
01209 #endif
01210
01211
01212
01213 #ifndef _WINSTL_NO_NAMESPACE
01214 # if defined(_STLSOFT_NO_NAMESPACE) || \
01215 defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
01216 }
01217 # else
01218 }
01219 }
01220 # endif
01221 #endif
01222
01223
01224
01225 #endif
01226
01227