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
00050
00058 #ifndef WINSTL_INCL_WINSTL_REGISTRY_HPP_REG_VALUE_SEQUENCE
00059 #define WINSTL_INCL_WINSTL_REGISTRY_HPP_REG_VALUE_SEQUENCE
00060
00061 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00062 # define WINSTL_VER_WINSTL_REGISTRY_HPP_REG_VALUE_SEQUENCE_MAJOR 3
00063 # define WINSTL_VER_WINSTL_REGISTRY_HPP_REG_VALUE_SEQUENCE_MINOR 7
00064 # define WINSTL_VER_WINSTL_REGISTRY_HPP_REG_VALUE_SEQUENCE_REVISION 2
00065 # define WINSTL_VER_WINSTL_REGISTRY_HPP_REG_VALUE_SEQUENCE_EDIT 125
00066 #endif
00067
00068
00069
00070
00071
00072 #ifndef WINSTL_INCL_WINSTL_H_WINSTL
00073 # include <winstl/winstl.h>
00074 #endif
00075 #ifndef WINSTL_INCL_WINSTL_REGISTRY_HPP_REGFWD
00076 # include <winstl/registry/regfwd.hpp>
00077 #endif
00078 #ifndef WINSTL_INCL_WINSTL_REGISTRY_UTIL_HPP_DEFS
00079 # include <winstl/registry/util/defs.hpp>
00080 #endif
00081 #ifndef WINSTL_INCL_WINSTL_REGISTRY_HPP_REG_TRAITS
00082 # include <winstl/registry/reg_traits.hpp>
00083 #endif
00084 #ifndef WINSTL_INCL_WINSTL_REGISTRY_HPP_REG_VALUE
00085 # include <winstl/registry/reg_value.hpp>
00086 #endif
00087 #ifndef WINSTL_INCL_WINSTL_REGISTRY_UTIL_HPP_SHARED_HANDLES
00088 # include <winstl/registry/util/shared_handles.hpp>
00089 #endif
00090 #ifndef STLSOFT_INCL_STLSOFT_MEMORY_HPP_AUTO_BUFFER
00091 # include <stlsoft/memory/auto_buffer.hpp>
00092 #endif
00093 #ifndef WINSTL_INCL_WINSTL_MEMORY_HPP_PROCESSHEAP_ALLOCATOR
00094 # include <winstl/memory/processheap_allocator.hpp>
00095 #endif
00096 #ifndef STLSOFT_INCL_STLSOFT_UTIL_STD_HPP_ITERATOR_HELPER
00097 # include <stlsoft/util/std/iterator_helper.hpp>
00098 #endif
00099 #ifndef STLSOFT_INCL_STLSOFT_COLLECTIONS_UTIL_HPP_COLLECTIONS
00100 # include <stlsoft/collections/util/collections.hpp>
00101 #endif
00102 #ifndef STLSOFT_INCL_STLSOFT_SMARTPTR_HPP_REF_PTR
00103 # include <stlsoft/smartptr/ref_ptr.hpp>
00104 #endif
00105 #ifndef STLSOFT_INCL_STLSOFT_SMARTPTR_HPP_SCOPED_HANDLE
00106 # include <stlsoft/smartptr/scoped_handle.hpp>
00107 #endif
00108
00109
00110
00111
00112
00113 #ifndef _WINSTL_NO_NAMESPACE
00114 # if defined(_STLSOFT_NO_NAMESPACE) || \
00115 defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00116
00117 namespace winstl
00118 {
00119 # else
00120
00121
00122 namespace stlsoft
00123 {
00124
00125 namespace winstl_project
00126 {
00127
00128 # endif
00129 #endif
00130
00131
00132
00133
00142 template< ss_typename_param_k C
00143 #ifdef STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT
00144 , ss_typename_param_k T = reg_traits<C>
00145 , ss_typename_param_k A = processheap_allocator<C>
00146 #else
00147 , ss_typename_param_k T
00148 , ss_typename_param_k A
00149 #endif
00150 >
00151 class basic_reg_value_sequence
00152 : public stlsoft_ns_qual(stl_collection_tag)
00153 {
00156 public:
00158 typedef C char_type;
00160 typedef T traits_type;
00162 typedef A allocator_type;
00164 typedef basic_reg_value_sequence<C, T, A> class_type;
00166 typedef basic_reg_value<C, T, A> value_type;
00168 typedef ss_typename_type_k traits_type::size_type size_type;
00170 typedef basic_reg_key<C, T, A> reg_key_type;
00172 typedef basic_reg_value_sequence_iterator<C, T, value_type, A> iterator;
00176 typedef iterator const_iterator;
00178 typedef value_type& reference;
00180 typedef value_type const& const_reference;
00182 #if defined(STLSOFT_COMPILER_IS_MSVC) && \
00183 _MSC_VER == 1100
00184
00185 typedef HKEY hkey_type;
00186 #else
00187 typedef ss_typename_type_k traits_type::hkey_type hkey_type;
00188 #endif
00190 typedef ws_ptrdiff_t difference_type;
00192 #if defined(STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT)
00193 typedef stlsoft_ns_qual(reverse_bidirectional_iterator_base) < iterator
00194 , value_type
00195 , value_type
00196 , void
00197 , difference_type
00198 > reverse_iterator;
00199 #endif
00201 typedef ws_bool_t bool_type;
00202 private:
00204 typedef ss_typename_type_k traits_type::result_type result_type;
00205 private:
00206 typedef stlsoft_ns_qual(auto_buffer_old)< char_type
00207 , allocator_type
00208 , CCH_REG_API_AUTO_BUFFER
00209 > buffer_type_;
00210 public:
00211 typedef hkey_type resource_type;
00213
00216 public:
00226 basic_reg_value_sequence( hkey_type hkey
00227 , char_type const *subKeyName
00228 , REGSAM accessMask = KEY_READ);
00240 basic_reg_value_sequence( hkey_type hkey
00241 , char_type const *subKeyName
00242 , REGSAM accessMask
00243 , bool_type bMonitorExternalInvalidation);
00250 ss_explicit_k basic_reg_value_sequence(reg_key_type const& key);
00258 basic_reg_value_sequence( reg_key_type const& key
00259 , REGSAM accessMask);
00269 basic_reg_value_sequence( reg_key_type const& key
00270 , REGSAM accessMask
00271 , bool_type bMonitorExternalInvalidation);
00273 ~basic_reg_value_sequence() stlsoft_throw_0();
00275
00278 public:
00282 iterator begin();
00286 iterator end();
00287
00288 #if defined(STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT)
00292 reverse_iterator rbegin();
00296 reverse_iterator rend();
00297 #endif
00299
00302 public:
00307 size_type current_size() const;
00311 size_type size() const;
00313 ws_bool_t empty() const;
00314
00316 hkey_type get_key_handle() const;
00318 hkey_type get() const;
00320
00323 private:
00324 registry_util::shared_handle *create_shared_handle_(result_type& res);
00325 static REGSAM validate_access_mask_(REGSAM accessMask, bool_type bMonitorExternalInvalidation);
00326 static hkey_type dup_key_(hkey_type hkey, REGSAM accessMask);
00328
00331 private:
00332 hkey_type m_hkey;
00333 const REGSAM m_accessMask;
00334 const bool_type m_bMonitorExternalInvalidation;
00336
00339 private:
00340 basic_reg_value_sequence(class_type const&);
00341 class_type& operator =(class_type const&);
00343 };
00344
00345
00350 typedef basic_reg_value_sequence<ws_char_a_t, reg_traits<ws_char_a_t>, processheap_allocator<ws_char_a_t> > reg_value_sequence_a;
00355 typedef basic_reg_value_sequence<ws_char_w_t, reg_traits<ws_char_w_t>, processheap_allocator<ws_char_w_t> > reg_value_sequence_w;
00360 typedef basic_reg_value_sequence<TCHAR, reg_traits<TCHAR>, processheap_allocator<TCHAR> > reg_value_sequence;
00361
00362
00372 template< ss_typename_param_k C
00373 , ss_typename_param_k T
00374 , ss_typename_param_k V
00375 , ss_typename_param_k A
00376 >
00377 class basic_reg_value_sequence_iterator
00378 : public stlsoft_ns_qual(iterator_base)<winstl_ns_qual_std(bidirectional_iterator_tag)
00379 , V
00380 , ws_ptrdiff_t
00381 , void
00382 , V
00383 >
00384 {
00387 public:
00389 typedef C char_type;
00391 typedef T traits_type;
00393 typedef V value_type;
00395 typedef A allocator_type;
00397 typedef basic_reg_value_sequence_iterator<C, T, V, A> class_type;
00399 typedef ss_typename_type_k traits_type::size_type size_type;
00401 typedef ss_typename_type_k traits_type::difference_type difference_type;
00403 typedef ss_typename_type_k traits_type::string_type string_type;
00405 typedef ws_sint32_t index_type;
00407 typedef ss_typename_type_k traits_type::hkey_type hkey_type;
00408 private:
00410 typedef ss_typename_type_k traits_type::result_type result_type;
00412 typedef ws_bool_t bool_type;
00413 private:
00414 typedef stlsoft_ns_qual(auto_buffer_old)< char_type
00415 , allocator_type
00416 , CCH_REG_API_AUTO_BUFFER
00417 > buffer_type_;
00419
00422 private:
00423 friend class basic_reg_value_sequence<C, T, A>;
00424
00426 basic_reg_value_sequence_iterator(registry_util::shared_handle *handle, char_type const* name, size_type cchName, index_type index, REGSAM accessMask)
00427 : m_handle(handle)
00428 , m_index(index)
00429 , m_name(name, cchName)
00430 , m_accessMask(accessMask)
00431 {
00432 WINSTL_ASSERT(NULL != m_handle);
00433 m_handle->test_reset_and_throw();
00434 m_handle->AddRef();
00435 }
00436 public:
00438 basic_reg_value_sequence_iterator();
00440 basic_reg_value_sequence_iterator(class_type const& rhs);
00442 ~basic_reg_value_sequence_iterator() stlsoft_throw_0();
00443
00445 class_type& operator =(class_type const& rhs);
00447
00450 public:
00451 string_type const& get_key_name() const;
00453
00456 public:
00458 class_type& operator ++();
00460 class_type& operator --();
00462 const class_type operator ++(int);
00464 const class_type operator --(int);
00466 const value_type operator *() const;
00468 ws_bool_t equal(class_type const& rhs) const;
00470 ws_bool_t operator ==(class_type const& rhs) const;
00472 ws_bool_t operator !=(class_type const& rhs) const;
00474
00477 private:
00478 static index_type sentinel_() stlsoft_throw_0();
00480
00483 private:
00484 registry_util::shared_handle *m_handle;
00485 index_type m_index;
00486 string_type m_name;
00487 REGSAM m_accessMask;
00489 };
00490
00492
00493
00494 #ifdef STLSOFT_UNITTEST
00495 # include "./unittest/reg_value_sequence_unittest_.h"
00496 #endif
00497
00499
00500
00501 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00502
00503
00504
00505 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
00506 inline registry_util::shared_handle* basic_reg_value_sequence<C, T, A>::create_shared_handle_(result_type& res)
00507 {
00508
00509
00510
00511
00512 registry_util::shared_handle* handle = NULL;
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 handle = NULL;
00530 #endif
00531 }
00532 else
00533 {
00534
00535 scoped_handle<HKEY> sh(hkey2, ::RegCloseKey);
00536
00537 handle = registry_util::create_shared_handle(hkey2, m_bMonitorExternalInvalidation, REG_NOTIFY_CHANGE_LAST_SET);
00538
00539 if(NULL == handle)
00540 {
00541 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00542 static const char message[] = "could not create shared enumeration context";
00543 DWORD err = ::GetLastError();
00544
00545 if(ERROR_ACCESS_DENIED == err)
00546 {
00547 STLSOFT_THROW_X(access_denied_exception(message, err));
00548 }
00549 else
00550 {
00551 STLSOFT_THROW_X(registry_exception(message, err));
00552 }
00553 #endif
00554 }
00555 else
00556 {
00557 sh.detach();
00558 }
00559 }
00560
00561 return handle;
00562 }
00563
00564 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
00565 inline REGSAM basic_reg_value_sequence<C, T, A>::validate_access_mask_(REGSAM accessMask, ss_typename_type_k basic_reg_value_sequence<C, T, A>::bool_type bMonitorExternalInvalidation)
00566 {
00567 if(bMonitorExternalInvalidation)
00568 {
00569 return accessMask | KEY_NOTIFY;
00570 }
00571 else
00572 {
00573 return accessMask & ~(KEY_NOTIFY);
00574 }
00575 }
00576
00577 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
00578 inline ss_typename_type_ret_k basic_reg_value_sequence<C, T, A>::hkey_type basic_reg_value_sequence<C, T, A>::dup_key_(ss_typename_type_k basic_reg_value_sequence<C, T, A>::hkey_type hkey, REGSAM accessMask)
00579 {
00580 result_type res;
00581 HKEY hkeyDup = traits_type::key_dup(hkey, accessMask, &res);
00582
00583 if(ERROR_SUCCESS != res)
00584 {
00585 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00586 static const char message[] = "could not duplicate key";
00587
00588 if(ERROR_ACCESS_DENIED == res)
00589 {
00590 STLSOFT_THROW_X(access_denied_exception(message, res));
00591 }
00592 else
00593 {
00594 STLSOFT_THROW_X(key_not_duplicated_exception(message, res));
00595 }
00596 #else
00597 hkeyDup = NULL;
00598 #endif
00599 }
00600
00601 return hkeyDup;
00602 }
00603
00604 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
00605 inline basic_reg_value_sequence<C, T, A>::basic_reg_value_sequence( ss_typename_type_k basic_reg_value_sequence<C, T, A>::hkey_type hkey
00606 , ss_typename_type_k basic_reg_value_sequence<C, T, A>::char_type const *subKeyName
00607 , REGSAM accessMask )
00608 : m_hkey(NULL)
00609 , m_accessMask(accessMask)
00610 , m_bMonitorExternalInvalidation(0 != (KEY_NOTIFY & accessMask))
00611 {
00612 result_type res;
00613
00614 if(ERROR_SUCCESS != (res = traits_type::reg_open_key(hkey, subKeyName, &m_hkey, accessMask)))
00615 {
00616 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00617 static const char message[] = "could not open key";
00618
00619 if(ERROR_ACCESS_DENIED == res)
00620 {
00621 STLSOFT_THROW_X(access_denied_exception(message, res));
00622 }
00623 else
00624 {
00625 STLSOFT_THROW_X(registry_exception(message, res));
00626 }
00627 #else
00628 m_hkey = NULL;
00629 #endif
00630 }
00631 }
00632
00633 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
00634 inline basic_reg_value_sequence<C, T, A>::basic_reg_value_sequence( ss_typename_type_k basic_reg_value_sequence<C, T, A>::hkey_type hkey
00635 , ss_typename_type_k basic_reg_value_sequence<C, T, A>::char_type const *subKeyName
00636 , REGSAM accessMask
00637 , ss_typename_type_k basic_reg_value_sequence<C, T, A>::bool_type bMonitorExternalInvalidation)
00638 : m_hkey(NULL)
00639 , m_accessMask(validate_access_mask_(accessMask, bMonitorExternalInvalidation))
00640 , m_bMonitorExternalInvalidation(bMonitorExternalInvalidation)
00641 {
00642 result_type res;
00643
00644 if(ERROR_SUCCESS != (res = traits_type::reg_open_key(hkey, subKeyName, &m_hkey, accessMask)))
00645 {
00646 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00647 static const char message[] = "could not open key";
00648
00649 if(ERROR_ACCESS_DENIED == res)
00650 {
00651 STLSOFT_THROW_X(access_denied_exception(message, res));
00652 }
00653 else
00654 {
00655 STLSOFT_THROW_X(registry_exception(message, res));
00656 }
00657 #else
00658 m_hkey = NULL;
00659 #endif
00660 }
00661 }
00662
00663 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
00664 inline basic_reg_value_sequence<C, T, A>::basic_reg_value_sequence(ss_typename_type_k basic_reg_value_sequence<C, T, A>::reg_key_type const& key)
00665 : m_hkey(dup_key_(key.m_hkey, key.get_access_mask()))
00666 , m_accessMask(key.get_access_mask())
00667 , m_bMonitorExternalInvalidation(0 != (KEY_NOTIFY & key.get_access_mask()))
00668 {
00669 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00670 if(NULL == m_hkey)
00671 {
00672 STLSOFT_THROW_X(registry_exception("Failed to take duplicate of key", ::GetLastError()));
00673 }
00674 #endif
00675 }
00676
00677 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
00678 inline basic_reg_value_sequence<C, T, A>::basic_reg_value_sequence( ss_typename_type_k basic_reg_value_sequence<C, T, A>::reg_key_type const& key
00679 , REGSAM accessMask)
00680 : m_hkey(dup_key_(key.m_hkey, accessMask))
00681 , m_accessMask(accessMask)
00682 , m_bMonitorExternalInvalidation(0 != (KEY_NOTIFY & accessMask))
00683 {
00684 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00685 if(NULL == m_hkey)
00686 {
00687 STLSOFT_THROW_X(registry_exception("Failed to take duplicate of key", ::GetLastError()));
00688 }
00689 #endif
00690 }
00691
00692 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
00693 inline basic_reg_value_sequence<C, T, A>::basic_reg_value_sequence( ss_typename_type_k basic_reg_value_sequence<C, T, A>::reg_key_type const& key
00694 , REGSAM accessMask
00695 , bool_type bMonitorExternalInvalidation)
00696 : m_hkey(dup_key_(key.m_hkey, validate_access_mask_(accessMask, bMonitorExternalInvalidation)))
00697 , m_accessMask(validate_access_mask_(accessMask, bMonitorExternalInvalidation))
00698 , m_bMonitorExternalInvalidation(bMonitorExternalInvalidation)
00699 {
00700 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00701 if(NULL == m_hkey)
00702 {
00703 STLSOFT_THROW_X(registry_exception("Failed to take duplicate of key", ::GetLastError()));
00704 }
00705 #endif
00706 }
00707
00708 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
00709 inline basic_reg_value_sequence<C, T, A>::~basic_reg_value_sequence() stlsoft_throw_0()
00710 {
00711 if(m_hkey != NULL)
00712 {
00713 ::RegCloseKey(m_hkey);
00714 }
00715 }
00716
00717 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
00718 inline ss_typename_type_ret_k basic_reg_value_sequence<C, T, A>::iterator basic_reg_value_sequence<C, T, A>::begin()
00719 {
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732 size_type cchName = 0;
00733 ws_uint32_t numEntries = 0;
00734 result_type res = traits_type::reg_query_info(m_hkey, NULL, NULL, NULL, NULL, NULL, &numEntries, &cchName, NULL, NULL, NULL);
00735
00736 if(ERROR_SUCCESS != res)
00737 {
00738 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00739 static const char message[] = "could not elicit value information";
00740
00741 if(ERROR_ACCESS_DENIED == res)
00742 {
00743 STLSOFT_THROW_X(access_denied_exception(message, res));
00744 }
00745 else
00746 {
00747 STLSOFT_THROW_X(registry_exception(message, res));
00748 }
00749 #else
00750 ;
00751 #endif
00752 }
00753 else
00754 {
00755 if(0 != numEntries)
00756 {
00757
00758 registry_util::shared_handle *handle = create_shared_handle_(res);
00759 ws_sint32_t index = 0;
00760
00761 if(NULL == handle)
00762 {
00763 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00764 static const char message[] = "could not create shared enumeration context";
00765
00766 if(ERROR_ACCESS_DENIED == res)
00767 {
00768 STLSOFT_THROW_X(access_denied_exception(message, res));
00769 }
00770 else
00771 {
00772 STLSOFT_THROW_X(registry_exception(message, res));
00773 }
00774 #else
00775 ;
00776 #endif
00777 }
00778 else
00779 {
00780 ref_ptr<registry_util::shared_handle> ref(handle, false);
00781
00782
00783 buffer_type_ buffer(++cchName);
00784
00785 for(; !buffer.empty(); )
00786 {
00787 cchName = buffer.size();
00788
00789 res = traits_type::reg_enum_value(m_hkey, 0, &buffer[0], &cchName);
00790
00791 if(ERROR_MORE_DATA == res)
00792 {
00793 if(!buffer.resize(2 * buffer.size()))
00794 {
00795 cchName = 0;
00796 index = const_iterator::sentinel_();
00797 break;
00798 }
00799
00800 continue;
00801 }
00802 else if(ERROR_SUCCESS != res)
00803 {
00804 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00805 static const char message[] = "could not enumerate values";
00806
00807 if(ERROR_ACCESS_DENIED == res)
00808 {
00809 STLSOFT_THROW_X(access_denied_exception(message, res));
00810 }
00811 else
00812 {
00813 STLSOFT_THROW_X(registry_exception(message, res));
00814 }
00815 #else
00816 cchName = 0;
00817 index = const_iterator::sentinel_();
00818 break;
00819 #endif
00820 }
00821 else
00822 {
00823 break;
00824 }
00825 }
00826
00827
00828 return iterator(handle, buffer.data(), cchName, index, m_accessMask);
00829 }
00830 }
00831 }
00832
00833 return end();
00834 }
00835
00836 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
00837 inline ss_typename_type_ret_k basic_reg_value_sequence<C, T, A>::iterator basic_reg_value_sequence<C, T, A>::end()
00838 {
00839 result_type res;
00840 registry_util::shared_handle *handle = create_shared_handle_(res);
00841 ref_ptr<registry_util::shared_handle> ref(handle, false);
00842 ws_sint32_t index = const_iterator::sentinel_();
00843
00844 if(NULL == handle)
00845 {
00846 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00847 STLSOFT_THROW_X(registry_exception("Failed to take duplicate of key", static_cast<DWORD>(res)));
00848 #else
00849 index = 0;
00850 #endif
00851 }
00852
00853 return iterator(handle, NULL, 0, index, m_accessMask);
00854 }
00855
00856 #if defined(STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT)
00857 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
00858 inline ss_typename_type_ret_k basic_reg_value_sequence<C, T, A>::reverse_iterator basic_reg_value_sequence<C, T, A>::rbegin()
00859 {
00860 return reverse_iterator(end());
00861 }
00862
00863 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
00864 inline ss_typename_type_ret_k basic_reg_value_sequence<C, T, A>::reverse_iterator basic_reg_value_sequence<C, T, A>::rend()
00865 {
00866 return reverse_iterator(begin());
00867 }
00868 #endif
00869
00870 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
00871 inline ss_typename_type_ret_k basic_reg_value_sequence<C, T, A>::size_type basic_reg_value_sequence<C, T, A>::size() const
00872 {
00873 return current_size();
00874 }
00875
00876 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
00877 inline ss_typename_type_ret_k basic_reg_value_sequence<C, T, A>::size_type basic_reg_value_sequence<C, T, A>::current_size() const
00878 {
00879 ws_uint32_t numEntries;
00880 result_type res = traits_type::reg_query_info(m_hkey, NULL, NULL, NULL, NULL, NULL, &numEntries, NULL, NULL, NULL, NULL);
00881
00882 if(ERROR_SUCCESS != res)
00883 {
00884 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00885 static const char message[] = "could not elicit number of values";
00886
00887 if(ERROR_ACCESS_DENIED == res)
00888 {
00889 STLSOFT_THROW_X(access_denied_exception(message, res));
00890 }
00891 else
00892 {
00893 STLSOFT_THROW_X(registry_exception(message, res));
00894 }
00895 #else
00896 numEntries = 0;
00897 #endif
00898 }
00899
00900 return static_cast<size_type>(numEntries);
00901 }
00902
00903 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
00904 inline ws_bool_t basic_reg_value_sequence<C, T, A>::empty() const
00905 {
00906 return 0 == size();
00907 }
00908
00909 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
00910 inline ss_typename_type_ret_k basic_reg_value_sequence<C, T, A>::hkey_type basic_reg_value_sequence<C, T, A>::get_key_handle() const
00911 {
00912 return m_hkey;
00913 }
00914
00915 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
00916 inline ss_typename_type_ret_k basic_reg_value_sequence<C, T, A>::hkey_type basic_reg_value_sequence<C, T, A>::get() const
00917 {
00918 return get_key_handle();
00919 }
00920
00921
00922
00923 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V, ss_typename_param_k A>
00924 inline ss_typename_type_ret_k basic_reg_value_sequence_iterator<C, T, V, A>::index_type basic_reg_value_sequence_iterator<C, T, V, A>::sentinel_() stlsoft_throw_0()
00925 {
00926 return 0x7fffffff;
00927 }
00928
00929 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V, ss_typename_param_k A>
00930 inline basic_reg_value_sequence_iterator<C, T, V, A>::basic_reg_value_sequence_iterator()
00931 : m_handle(NULL)
00932 , m_index(sentinel_())
00933 , m_name()
00934 , m_accessMask(KEY_READ)
00935 {}
00936
00937 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V, ss_typename_param_k A>
00938 inline basic_reg_value_sequence_iterator<C, T, V, A>::basic_reg_value_sequence_iterator(class_type const& rhs)
00939 : m_handle(rhs.m_handle)
00940 , m_index(rhs.m_index)
00941 , m_name(rhs.m_name)
00942 , m_accessMask(rhs.m_accessMask)
00943 {
00944 if(NULL != m_handle)
00945 {
00946 m_handle->AddRef();
00947 }
00948 }
00949
00950 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V, ss_typename_param_k A>
00951 inline ss_typename_type_ret_k basic_reg_value_sequence_iterator<C, T, V, A>::class_type& basic_reg_value_sequence_iterator<C, T, V, A>::operator =(ss_typename_type_k basic_reg_value_sequence_iterator<C, T, V, A>::class_type const& rhs)
00952 {
00953 registry_util::shared_handle *this_handle;
00954
00955 m_index = rhs.m_index;
00956 m_name = rhs.m_name;
00957
00958 this_handle = m_handle;
00959 m_handle = rhs.m_handle;
00960 m_accessMask = rhs.m_accessMask;
00961
00962 if(NULL != m_handle)
00963 {
00964 m_handle->AddRef();
00965 }
00966
00967 if(NULL != this_handle)
00968 {
00969 this_handle->Release();
00970 }
00971
00972 return *this;
00973 }
00974
00975 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V, ss_typename_param_k A>
00976 inline basic_reg_value_sequence_iterator<C, T, V, A>::~basic_reg_value_sequence_iterator() stlsoft_throw_0()
00977 {
00978 if(NULL != m_handle)
00979 {
00980 m_handle->Release();
00981 }
00982 }
00983
00984 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V, ss_typename_param_k A>
00985 inline const ss_typename_type_k basic_reg_value_sequence_iterator<C, T, V, A>::string_type& basic_reg_value_sequence_iterator<C, T, V, A>::get_key_name() const
00986 {
00987 return m_name;
00988 }
00989
00990 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V, ss_typename_param_k A>
00991 inline ss_typename_type_ret_k basic_reg_value_sequence_iterator<C, T, V, A>::class_type& basic_reg_value_sequence_iterator<C, T, V, A>::operator ++()
00992 {
00993 WINSTL_MESSAGE_ASSERT("Attempting to increment an invalid iterator!", NULL != m_handle);
00994 WINSTL_MESSAGE_ASSERT("Attempting to increment an invalid iterator!", sentinel_() != m_index);
00995
00996
00997 size_type cchName = 0;
00998 result_type res = traits_type::reg_query_info(m_handle->m_hkey, NULL, NULL, NULL, NULL, NULL, NULL, &cchName, NULL, NULL, NULL);
00999
01000 if(ERROR_SUCCESS != res)
01001 {
01002 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
01003 static const char message[] = "could not elicit value information";
01004
01005 if(ERROR_ACCESS_DENIED == res)
01006 {
01007 STLSOFT_THROW_X(access_denied_exception(message, res));
01008 }
01009 else
01010 {
01011 STLSOFT_THROW_X(registry_exception(message, res));
01012 }
01013 #else
01014 m_index = sentinel_();
01015 #endif
01016 }
01017 else
01018 {
01019 buffer_type_ buffer(++cchName);
01020
01021 for(; !buffer.empty(); buffer.resize(2 * buffer.size()))
01022 {
01023 cchName = buffer.size();
01024
01025 res = traits_type::reg_enum_value(m_handle->m_hkey, static_cast<ws_dword_t>(1 + m_index), &buffer[0], &cchName);
01026
01027 if(ERROR_MORE_DATA == res)
01028 {
01029 continue;
01030 }
01031 else if(ERROR_NO_MORE_ITEMS == res)
01032 {
01033 m_index = sentinel_();
01034 break;
01035 }
01036 else if(ERROR_SUCCESS != res)
01037 {
01038 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
01039 static const char message[] = "could not enumerate values";
01040
01041 if(ERROR_ACCESS_DENIED == res)
01042 {
01043 STLSOFT_THROW_X(access_denied_exception(message, res));
01044 }
01045 else
01046 {
01047 STLSOFT_THROW_X(registry_exception(message, res));
01048 }
01049 #else
01050 m_index = sentinel_();
01051 break;
01052 #endif
01053 }
01054 else
01055 {
01056 m_name.assign(buffer.data(), cchName);
01057
01058 ++m_index;
01059
01060 break;
01061 }
01062 }
01063 }
01064
01065 m_handle->test_reset_and_throw();
01066
01067 return *this;
01068 }
01069
01070 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V, ss_typename_param_k A>
01071 inline ss_typename_type_ret_k basic_reg_value_sequence_iterator<C, T, V, A>::class_type& basic_reg_value_sequence_iterator<C, T, V, A>::operator --()
01072 {
01073 WINSTL_MESSAGE_ASSERT("Attempting to decrement an invalid iterator", NULL != m_handle);
01074
01075
01076 size_type cchName = 0;
01077 ws_uint32_t numEntries = 0;
01078 result_type res = traits_type::reg_query_info(m_handle->m_hkey, NULL, NULL, NULL, NULL, NULL, &numEntries, &cchName, NULL, NULL, NULL);
01079
01080 if(ERROR_SUCCESS != res)
01081 {
01082 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
01083 static const char message[] = "could not elicit value information";
01084
01085 if(ERROR_ACCESS_DENIED == res)
01086 {
01087 STLSOFT_THROW_X(access_denied_exception(message, res));
01088 }
01089 else
01090 {
01091 STLSOFT_THROW_X(registry_exception(message, res));
01092 }
01093 #else
01094 m_index = sentinel_();
01095 #endif
01096 }
01097 else
01098 {
01099 buffer_type_ buffer(++cchName);
01100 ws_dword_t index;
01101
01102
01103 if(m_index == sentinel_())
01104 {
01105
01106 index = numEntries - 1;
01107 }
01108 else
01109 {
01110
01111 index = m_index - 1;
01112 }
01113
01114 for(; !buffer.empty(); buffer.resize(2 * buffer.size()))
01115 {
01116 cchName = buffer.size();
01117
01118 res = traits_type::reg_enum_value(m_handle->m_hkey, index, &buffer[0], &cchName);
01119
01120 if(ERROR_MORE_DATA == res)
01121 {
01122 continue;
01123 }
01124 else if(ERROR_SUCCESS != res)
01125 {
01126 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
01127 static const char message[] = "could not elicit value information";
01128
01129 if(ERROR_ACCESS_DENIED == res)
01130 {
01131 STLSOFT_THROW_X(access_denied_exception(message, res));
01132 }
01133 else
01134 {
01135 STLSOFT_THROW_X(registry_exception(message, res));
01136 }
01137 #else
01138 m_index = sentinel_();
01139 #endif
01140 }
01141 else
01142 {
01143 m_name.assign(buffer.data(), cchName);
01144
01145 m_index = index;
01146
01147 break;
01148 }
01149 }
01150 }
01151
01152 m_handle->test_reset_and_throw();
01153
01154 return *this;
01155 }
01156
01157 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V, ss_typename_param_k A>
01158 inline const ss_typename_type_k basic_reg_value_sequence_iterator<C, T, V, A>::class_type basic_reg_value_sequence_iterator<C, T, V, A>::operator ++(int)
01159 {
01160 class_type ret(*this);
01161
01162 operator ++();
01163
01164 return ret;
01165 }
01166
01167 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V, ss_typename_param_k A>
01168 inline const ss_typename_type_k basic_reg_value_sequence_iterator<C, T, V, A>::class_type basic_reg_value_sequence_iterator<C, T, V, A>::operator --(int)
01169 {
01170 class_type ret(*this);
01171
01172 operator --();
01173
01174 return ret;
01175 }
01176
01177 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V, ss_typename_param_k A>
01178 inline const ss_typename_type_k basic_reg_value_sequence_iterator<C, T, V, A>::value_type basic_reg_value_sequence_iterator<C, T, V, A>::operator *() const
01179 {
01180 WINSTL_MESSAGE_ASSERT("Attempting to dereference an invalid iterator", NULL != m_handle);
01181
01182 m_handle->test_reset_and_throw();
01183
01184 return value_type(m_handle->m_hkey, m_name);
01185 }
01186
01187 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V, ss_typename_param_k A>
01188 inline ws_bool_t basic_reg_value_sequence_iterator<C, T, V, A>::equal(class_type const& rhs) const
01189 {
01190 return m_index == rhs.m_index;
01191 }
01192
01193 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V, ss_typename_param_k A>
01194 inline ws_bool_t basic_reg_value_sequence_iterator<C, T, V, A>::operator ==(class_type const& rhs) const
01195 {
01196 return equal(rhs);
01197 }
01198
01199 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V, ss_typename_param_k A>
01200 inline ws_bool_t basic_reg_value_sequence_iterator<C, T, V, A>::operator !=(class_type const& rhs) const
01201 {
01202 return !equal(rhs);
01203 }
01204
01205 #endif
01206
01207
01208
01209 #ifndef _WINSTL_NO_NAMESPACE
01210 # if defined(_STLSOFT_NO_NAMESPACE) || \
01211 defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
01212 }
01213 # else
01214 }
01215 }
01216 # endif
01217 #endif
01218
01219
01220
01221 #endif
01222
01223