You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1548 lines
64 KiB

  1. /* /////////////////////////////////////////////////////////////////////////
  2. * File: winstl/registry/reg_key.hpp
  3. *
  4. * Purpose: Contains the basic_reg_key class template, and ANSI
  5. * and Unicode specialisations thereof.
  6. *
  7. * Created: 19th January 2002
  8. * Updated: 21st February 2012
  9. *
  10. * Thanks: To Sam Fisher for spotting the defect in the set_value_()
  11. * overload for REG_MULTI_SZ values (widestring only).
  12. *
  13. * Home: http://stlsoft.org/
  14. *
  15. * Copyright (c) 2002-2012, Matthew Wilson and Synesis Software
  16. * All rights reserved.
  17. *
  18. * Redistribution and use in source and binary forms, with or without
  19. * modification, are permitted provided that the following conditions are met:
  20. *
  21. * - Redistributions of source code must retain the above copyright notice, this
  22. * list of conditions and the following disclaimer.
  23. * - Redistributions in binary form must reproduce the above copyright notice,
  24. * this list of conditions and the following disclaimer in the documentation
  25. * and/or other materials provided with the distribution.
  26. * - Neither the name(s) of Matthew Wilson and Synesis Software nor the names of
  27. * any contributors may be used to endorse or promote products derived from
  28. * this software without specific prior written permission.
  29. *
  30. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  31. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  32. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  33. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  34. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  35. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  36. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  37. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  38. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  39. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  40. * POSSIBILITY OF SUCH DAMAGE.
  41. *
  42. * ////////////////////////////////////////////////////////////////////// */
  43. /** \file winstl/registry/reg_key.hpp
  44. *
  45. * \brief [C++ only] Definition of the winstl::basic_reg_key class template
  46. * (\ref group__library__windows_registry "Windows Registry" Library).
  47. */
  48. #ifndef WINSTL_INCL_WINSTL_REGISTRY_HPP_REG_KEY
  49. #define WINSTL_INCL_WINSTL_REGISTRY_HPP_REG_KEY
  50. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  51. # define WINSTL_VER_WINSTL_REGISTRY_HPP_REG_KEY_MAJOR 3
  52. # define WINSTL_VER_WINSTL_REGISTRY_HPP_REG_KEY_MINOR 9
  53. # define WINSTL_VER_WINSTL_REGISTRY_HPP_REG_KEY_REVISION 9
  54. # define WINSTL_VER_WINSTL_REGISTRY_HPP_REG_KEY_EDIT 136
  55. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  56. /* /////////////////////////////////////////////////////////////////////////
  57. * Includes
  58. */
  59. #ifndef WINSTL_INCL_WINSTL_H_WINSTL
  60. # include <winstl/winstl.h>
  61. #endif /* !WINSTL_INCL_WINSTL_H_WINSTL */
  62. #ifndef WINSTL_INCL_WINSTL_REGISTRY_HPP_REGFWD
  63. # include <winstl/registry/regfwd.hpp>
  64. #endif /* !WINSTL_INCL_WINSTL_REGISTRY_HPP_REGFWD */
  65. #ifndef WINSTL_INCL_WINSTL_REGISTRY_UTIL_HPP_DEFS
  66. # include <winstl/registry/util/defs.hpp>
  67. #endif /* !WINSTL_INCL_WINSTL_REGISTRY_UTIL_HPP_DEFS */
  68. #ifndef WINSTL_INCL_WINSTL_REGISTRY_HPP_REG_TRAITS
  69. # include <winstl/registry/reg_traits.hpp>
  70. #endif /* !WINSTL_INCL_WINSTL_REGISTRY_HPP_REG_TRAITS */
  71. #if defined(STLSOFT_COMPILER_IS_DMC)
  72. # ifndef WINSTL_INCL_WINSTL_REGISTRY_HPP_REG_VALUE
  73. # include <winstl/registry/reg_value.hpp>
  74. # endif /* !WINSTL_INCL_WINSTL_REGISTRY_HPP_REG_VALUE */
  75. #endif /* compiler */
  76. #ifndef WINSTL_INCL_WINSTL_REGISTRY_ERROR_HPP_EXCEPTIONS
  77. # include <winstl/registry/error/exceptions.hpp>
  78. #endif /* !WINSTL_INCL_WINSTL_REGISTRY_ERROR_HPP_EXCEPTIONS */
  79. #ifndef STLSOFT_INCL_STLSOFT_MEMORY_HPP_AUTO_BUFFER
  80. # include <stlsoft/memory/auto_buffer.hpp>
  81. #endif /* !STLSOFT_INCL_STLSOFT_MEMORY_HPP_AUTO_BUFFER */
  82. #ifndef WINSTL_INCL_WINSTL_MEMORY_HPP_PROCESSHEAP_ALLOCATOR
  83. # include <winstl/memory/processheap_allocator.hpp>
  84. #endif /* !WINSTL_INCL_WINSTL_MEMORY_HPP_PROCESSHEAP_ALLOCATOR */
  85. #ifndef WINSTL_INCL_SHIMS_ATTRIBUTE_HPP_GET_HKEY
  86. # include <winstl/shims/attribute/get_HKEY.hpp>
  87. #endif /* !WINSTL_INCL_SHIMS_ATTRIBUTE_HPP_GET_HKEY */
  88. #ifndef STLSOFT_INCL_STLSOFT_SHIMS_ACCESS_HPP_STRING
  89. # include <stlsoft/shims/access/string.hpp>
  90. #endif /* !STLSOFT_INCL_STLSOFT_SHIMS_ACCESS_HPP_STRING */
  91. #ifndef STLSOFT_INCL_STLSOFT_META_HPP_YESNO
  92. # include <stlsoft/meta/yesno.hpp>
  93. #endif /* !STLSOFT_INCL_STLSOFT_META_HPP_YESNO */
  94. #ifndef STLSOFT_INCL_STLSOFT_UTIL_HPP_STD_SWAP
  95. # include <stlsoft/util/std_swap.hpp>
  96. #endif /* !STLSOFT_INCL_STLSOFT_UTIL_HPP_STD_SWAP */
  97. #ifndef STLSOFT_INCL_STLSOFT_ITERATORS_HPP_TRANSFORM_ITERATOR
  98. # include <stlsoft/iterators/transform_iterator.hpp>
  99. #endif /* !STLSOFT_INCL_STLSOFT_ITERATORS_HPP_TRANSFORM_ITERATOR */
  100. #ifndef STLSOFT_INCL_NUMERIC
  101. # define STLSOFT_INCL_NUMERIC
  102. # include <numeric>
  103. #endif /* !STLSOFT_INCL_NUMERIC */
  104. #ifndef STLSOFT_INCL_FUNCTIONAL
  105. # define STLSOFT_INCL_FUNCTIONAL
  106. # include <functional>
  107. #endif /* !STLSOFT_INCL_FUNCTIONAL */
  108. #ifdef STLSOFT_UNITTEST
  109. # include <winstl/registry/reg_value.hpp>
  110. #endif /* STLSOFT_UNITTEST */
  111. /* /////////////////////////////////////////////////////////////////////////
  112. * Namespace
  113. */
  114. #ifndef _WINSTL_NO_NAMESPACE
  115. # if defined(_STLSOFT_NO_NAMESPACE) || \
  116. defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
  117. /* There is no stlsoft namespace, so must define ::winstl */
  118. namespace winstl
  119. {
  120. # else
  121. /* Define stlsoft::winstl_project */
  122. namespace stlsoft
  123. {
  124. namespace winstl_project
  125. {
  126. # endif /* _STLSOFT_NO_NAMESPACE */
  127. #endif /* !_WINSTL_NO_NAMESPACE */
  128. /* /////////////////////////////////////////////////////////////////////////
  129. * Classes
  130. */
  131. /** Represents a registry key, and provides methods for manipulating its
  132. * values and sub-keys.
  133. *
  134. * \ingroup group__library__windows_registry
  135. *
  136. * This class acts as the value type of classes that manipulate registry keys
  137. * and encapsulates the concept of a registry key.
  138. *
  139. * \param C The character type
  140. * \param T The traits type. On translators that support default template arguments this defaults to reg_traits<C>
  141. * \param A The allocator type. On translators that support default template arguments this defaults to processheap_allocator<C>
  142. */
  143. template< ss_typename_param_k C
  144. #ifdef STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT
  145. , ss_typename_param_k T = reg_traits<C>
  146. , ss_typename_param_k A = processheap_allocator<C>
  147. #else /* ? STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT */
  148. , ss_typename_param_k T /* = reg_traits<C> */
  149. , ss_typename_param_k A /* = processheap_allocator<C> */
  150. #endif /* STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT */
  151. >
  152. class basic_reg_key
  153. {
  154. /// \name Member Types
  155. /// @{
  156. public:
  157. /// The character type
  158. typedef C char_type;
  159. /// The traits type
  160. typedef T traits_type;
  161. /// The allocator type
  162. typedef A allocator_type;
  163. /// The current parameterisation of the type
  164. typedef basic_reg_key<C, T, A> class_type;
  165. /// The size type
  166. typedef ss_typename_type_k traits_type::size_type size_type;
  167. /// The string type
  168. typedef ss_typename_type_k traits_type::string_type string_type;
  169. /// The key type
  170. #if defined(STLSOFT_COMPILER_IS_MSVC) && \
  171. _MSC_VER == 1100
  172. /* WSCB: VC5 has an internal compiler error if use traits_type::hkey_type */
  173. typedef HKEY hkey_type;
  174. #else /* ? compiler */
  175. typedef ss_typename_type_k traits_type::hkey_type hkey_type;
  176. #endif /* compiler */
  177. /// The Boolean type
  178. typedef ws_bool_t bool_type;
  179. /// The type of the key's values
  180. typedef basic_reg_value<C, T, A> key_value_type;
  181. #if 0
  182. /// The type of the sub-key collection
  183. typedef basic_reg_key_sequence<C, T, A> subkeys_collection_type;
  184. /// The type of the value collection
  185. typedef basic_reg_value_sequence<C, T, A> value_collection_type;
  186. #endif /* 0 */
  187. private:
  188. /// The results type of the Registry API
  189. typedef ss_typename_type_k traits_type::result_type result_type;
  190. public:
  191. typedef hkey_type resource_type;
  192. /// @}
  193. /// \name Construction
  194. /// @{
  195. private:
  196. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  197. friend class basic_reg_value_sequence<C, T, A>;
  198. friend class basic_reg_key_sequence<C, T, A>;
  199. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  200. #if defined(STLSOFT_COMPILER_IS_MSVC) && \
  201. ( _MSC_VER == 1200 || \
  202. _MSC_VER == 1300)
  203. public:
  204. #endif /* compiler */
  205. basic_reg_key(hkey_type* hkey, string_type const& keyName, REGSAM accessMask);
  206. public:
  207. /// Default constructor
  208. basic_reg_key();
  209. /** Construct from the named sub-key of the given parent
  210. *
  211. * \param hkeyParent A handle to the parent key, whose named subkey is
  212. * to be opened.
  213. * \param keyName The name of the subkey to open. If <code>NULL</code>
  214. * or the empty string, then a copy of <code>hkeyParent</code> will be
  215. * opened.
  216. * \param accessMask A mask of <code>KEY_*</code> flags that define the
  217. * required access to the key. Defaults to KEY_ALL_ACCESS.
  218. *
  219. * \exception winstl::registry_exception If \ref page__exception_agnostic "exception handling is enabled",
  220. * an instance of \link winstl::registry_exception registry_exception\endlink
  221. * will be thrown indicating why the given key could not be opened. If not,
  222. * then the instance constructed will be empty, as denoted by a <code>NULL</code>
  223. * value returned from the get_key_handle() method.
  224. */
  225. basic_reg_key(hkey_type hkeyParent, char_type const* keyName, REGSAM accessMask = KEY_ALL_ACCESS)
  226. : m_name(keyName)
  227. , m_hkey(open_key_(hkeyParent, keyName, accessMask))
  228. , m_accessMask(accessMask)
  229. {} // Implementation is within class, otherwise VC5 will not link
  230. #ifdef STLSOFT_CF_MEMBER_TEMPLATE_FUNCTION_SUPPORT
  231. /** Construct from the named sub-key of the given parent
  232. *
  233. * \param hkeyParent A handle to the parent key, whose named subkey is
  234. * to be opened.
  235. * \param keyName The name of the subkey to open. If <code>NULL</code>
  236. * or the empty string, then a copy of <code>hkeyParent</code> will be
  237. * opened.
  238. * \param accessMask A mask of <code>KEY_*</code> flags that define the
  239. * required access to the key. Defaults to KEY_ALL_ACCESS.
  240. *
  241. * \exception winstl::registry_exception If \ref page__exception_agnostic "exception handling is enabled",
  242. * an instance of \link winstl::registry_exception registry_exception\endlink
  243. * will be thrown indicating why the given key could not be opened. If not,
  244. * then the instance constructed will be empty, as denoted by a <code>NULL</code>
  245. * value returned from the get_key_handle() method.
  246. */
  247. template <ss_typename_param_k S>
  248. basic_reg_key(hkey_type hkeyParent, S const& keyName, REGSAM accessMask = KEY_ALL_ACCESS)
  249. : m_name(keyName)
  250. , m_hkey(open_key_(hkeyParent, stlsoft_ns_qual(c_str_ptr)(keyName), accessMask))
  251. , m_accessMask(accessMask)
  252. {} // Implementation is within class, otherwise VC5 will not link
  253. #endif /* STLSOFT_CF_MEMBER_TEMPLATE_FUNCTION_SUPPORT */
  254. /** Construct from the named sub-key of the given parent
  255. *
  256. * \param keyParent A handle to the parent key, whose named subkey is
  257. * to be opened.
  258. * \param keyName The name of the subkey to open. If <code>NULL</code>
  259. * or the empty string, then a copy of <code>keyParent</code> will be
  260. * opened.
  261. * \param accessMask A mask of <code>KEY_*</code> flags that define the
  262. * required access to the key. Defaults to KEY_ALL_ACCESS.
  263. *
  264. * \exception winstl::registry_exception If \ref page__exception_agnostic "exception handling is enabled",
  265. * an instance of \link winstl::registry_exception registry_exception\endlink
  266. * will be thrown indicating why the given key could not be opened. If not,
  267. * then the instance constructed will be empty, as denoted by a <code>NULL</code>
  268. * value returned from the get_key_handle() method.
  269. */
  270. basic_reg_key(class_type const& keyParent, char_type const* keyName, REGSAM accessMask = KEY_ALL_ACCESS)
  271. : m_name(keyName)
  272. , m_hkey(open_key_(keyParent.get_key_handle(), keyName, accessMask))
  273. , m_accessMask(accessMask)
  274. {} // Implementation is within class, otherwise VC5 will not link
  275. #ifdef STLSOFT_CF_MEMBER_TEMPLATE_FUNCTION_SUPPORT
  276. /** Construct from the named sub-key of the given parent
  277. *
  278. * \param keyParent A handle to the parent key, whose named subkey is
  279. * to be opened.
  280. * \param keyName The name of the subkey to open. If <code>NULL</code>
  281. * or the empty string, then a copy of <code>keyParent</code> will be
  282. * opened.
  283. * \param accessMask A mask of <code>KEY_*</code> flags that define the
  284. * required access to the key. Defaults to KEY_ALL_ACCESS.
  285. *
  286. * \exception winstl::registry_exception If \ref page__exception_agnostic "exception handling is enabled",
  287. * an instance of \link winstl::registry_exception registry_exception\endlink
  288. * will be thrown indicating why the given key could not be opened. If not,
  289. * then the instance constructed will be empty, as denoted by a <code>NULL</code>
  290. * value returned from the get_key_handle() method.
  291. */
  292. template <ss_typename_param_k S>
  293. basic_reg_key(class_type const& keyParent, S const& keyName, REGSAM accessMask = KEY_ALL_ACCESS)
  294. : m_name(keyName)
  295. , m_hkey(open_key_(keyParent.get_key_handle(), stlsoft_ns_qual(c_str_ptr)(keyName), accessMask))
  296. , m_accessMask(accessMask)
  297. {} // Implementation is within class, otherwise VC5 will not link
  298. #endif /* STLSOFT_CF_MEMBER_TEMPLATE_FUNCTION_SUPPORT */
  299. /** Constructs an instance as a (logical) copy of another.
  300. *
  301. * \param rhs Instance whose key will be opened by the new instance.
  302. *
  303. * \note The instance will hold a <i>different</i> handle to the
  304. * <i>same</i> registry key.
  305. *
  306. * \exception winstl::registry_exception If \ref page__exception_agnostic "exception handling is enabled",
  307. * an instance of \link winstl::registry_exception registry_exception\endlink
  308. * will be thrown indicating why the given key could not be opened. If not,
  309. * then the instance constructed will be empty, as denoted by a <code>NULL</code>
  310. * value returned from the get_key_handle() method.
  311. */
  312. basic_reg_key(class_type const& rhs);
  313. /** Constructs an instance as a (logical) copy of another, but with different permissions.
  314. *
  315. * \param rhs Instance whose key will be opened by the new instance.
  316. * \param accessMask The permissions for the new instance.
  317. *
  318. * \note The instance will hold a <i>different</i> handle to the
  319. * <i>same</i> registry key.
  320. *
  321. * \exception winstl::registry_exception If \ref page__exception_agnostic "exception handling is enabled",
  322. * an instance of \link winstl::registry_exception registry_exception\endlink
  323. * will be thrown indicating why the given key could not be opened. If not,
  324. * then the instance constructed will be empty, as denoted by a <code>NULL</code>
  325. * value returned from the get_key_handle() method.
  326. */
  327. basic_reg_key(class_type const& rhs, REGSAM accessMask);
  328. /// Destructor
  329. ///
  330. /// Releases any resources allocated by the instance, including closing the
  331. /// underlying registry key.
  332. ~basic_reg_key() stlsoft_throw_0();
  333. /// Copy assignment operator
  334. class_type& operator =(class_type const& rhs);
  335. /// @}
  336. /// \name Attributes
  337. /// @{
  338. public:
  339. /// The name of the key
  340. string_type const &name() const;
  341. /// The registry class of the key
  342. string_type reg_class() const;
  343. /// The number of sub-keys
  344. ///
  345. /// \note This is not a constant-time operation
  346. size_type num_sub_keys() const;
  347. /// The number of values
  348. ///
  349. /// \note This is not a constant-time operation
  350. size_type num_values() const;
  351. /// Indicates whether the sub-key exists
  352. ///
  353. /// \param subKeyName The name of the sub-key to test
  354. template <ss_typename_param_k S>
  355. bool_type has_sub_key(S const& subKeyName)
  356. {
  357. return this->has_sub_key_(stlsoft_ns_qual(c_str_ptr)(subKeyName));
  358. }
  359. /// Indicates whether the value exists
  360. ///
  361. /// \param valueName The name of the value to test
  362. template <ss_typename_param_k S>
  363. bool_type has_value(S const& valueName)
  364. {
  365. return this->has_value_(stlsoft_ns_qual(c_str_ptr)(valueName));
  366. }
  367. /** The handle to the underlying Registry API key.
  368. *
  369. * \note If \ref page__exception_agnostic "exception handling is not enabled",
  370. * then this method will return <code>NULL</code> in the case where an
  371. * instance constructor failed to open the key with the requested permissions.
  372. */
  373. hkey_type get_key_handle() const;
  374. /// The handle to the underlying Registry API key.
  375. ///
  376. /// \note Equivalent to get_key_handle()
  377. hkey_type get() const;
  378. #if 0
  379. subkeys_collection_type subkeys() const;
  380. value_collection_type values() const;
  381. #endif /* 0 */
  382. /// The access mask associated with the key
  383. REGSAM get_access_mask() const;
  384. /// @}
  385. /// \name Sub-key operations
  386. /// @{
  387. public:
  388. /// Opens the named sub-key of this key
  389. class_type open_sub_key(char_type const* subKeyName, REGSAM accessMask = KEY_ALL_ACCESS);
  390. #ifdef STLSOFT_CF_MEMBER_TEMPLATE_FUNCTION_SUPPORT
  391. template <ss_typename_param_k S>
  392. class_type open_sub_key(S const& subKeyName, REGSAM accessMask = KEY_ALL_ACCESS)
  393. {
  394. return open_sub_key_(stlsoft_ns_qual(c_str_ptr)(subKeyName), accessMask);
  395. }
  396. #endif /* STLSOFT_CF_MEMBER_TEMPLATE_FUNCTION_SUPPORT */
  397. /** Creates a named sub-key of this key
  398. *
  399. * \param subKeyName Name of the subkey to created. If <code>NULL</code> or the
  400. * empty string, then the function returns a copy of the callee.
  401. * \param accessMask A mask of <code>KEY_*</code> flags that define the
  402. * required access to the key. Defaults to KEY_ALL_ACCESS.
  403. *
  404. * \exception winstl::registry_exception If \ref page__exception_agnostic "exception handling is enabled",
  405. * an instance of \link winstl::registry_exception registry_exception\endlink
  406. * will be thrown indicating why the given key could not be created. If not,
  407. * then the instance constructed will be empty, as denoted by a <code>NULL</code>
  408. * value returned from the get_key_handle() method.
  409. */
  410. class_type create_sub_key(char_type const* subKeyName, REGSAM accessMask = KEY_ALL_ACCESS);
  411. #ifdef STLSOFT_CF_MEMBER_TEMPLATE_FUNCTION_SUPPORT
  412. /** Creates a named sub-key of this key
  413. *
  414. * \param subKeyName Name of the subkey to created. If <code>NULL</code> or the
  415. * empty string, then the function returns a copy of the callee.
  416. * \param accessMask A mask of <code>KEY_*</code> flags that define the
  417. * required access to the key. Defaults to KEY_ALL_ACCESS.
  418. *
  419. * \exception winstl::registry_exception If \ref page__exception_agnostic "exception handling is enabled",
  420. * an instance of \link winstl::registry_exception registry_exception\endlink
  421. * will be thrown indicating why the given key could not be created. If not,
  422. * then the instance constructed will be empty, as denoted by a <code>NULL</code>
  423. * value returned from the get_key_handle() method.
  424. */
  425. template <ss_typename_param_k S>
  426. class_type create_sub_key(S const& subKeyName, REGSAM accessMask = KEY_ALL_ACCESS)
  427. {
  428. return create_sub_key_(stlsoft_ns_qual(c_str_ptr)(subKeyName), accessMask);
  429. }
  430. #endif /* STLSOFT_CF_MEMBER_TEMPLATE_FUNCTION_SUPPORT */
  431. /** Creates a named sub-key of a given key
  432. *
  433. * \param hkey The parent registry key.
  434. * \param subKeyName Name of the subkey to created. If <code>NULL</code> or the
  435. * empty string, then the function returns a copy of the callee.
  436. * \param accessMask A mask of <code>KEY_*</code> flags that define the
  437. * required access to the key. Defaults to KEY_ALL_ACCESS.
  438. *
  439. * \exception winstl::registry_exception If \ref page__exception_agnostic "exception handling is enabled",
  440. * an instance of \link winstl::registry_exception registry_exception\endlink
  441. * will be thrown indicating why the given key could not be created. If not,
  442. * then the instance constructed will be empty, as denoted by a <code>NULL</code>
  443. * value returned from the get_key_handle() method.
  444. */
  445. static class_type create_key(HKEY hkey, char_type const* subKeyName, REGSAM accessMask = KEY_ALL_ACCESS);
  446. #ifdef STLSOFT_CF_MEMBER_TEMPLATE_FUNCTION_SUPPORT
  447. /** Creates a named sub-key of this key
  448. *
  449. * \param key The parent registry key.
  450. * \param subKeyName Name of the subkey to created. If <code>NULL</code> or the
  451. * empty string, then the function returns a copy of the callee.
  452. * \param accessMask A mask of <code>KEY_*</code> flags that define the
  453. * required access to the key. Defaults to KEY_ALL_ACCESS.
  454. *
  455. * \exception winstl::registry_exception If \ref page__exception_agnostic "exception handling is enabled",
  456. * an instance of \link winstl::registry_exception registry_exception\endlink
  457. * will be thrown indicating why the given key could not be created. If not,
  458. * then the instance constructed will be empty, as denoted by a <code>NULL</code>
  459. * value returned from the get_key_handle() method.
  460. */
  461. template <ss_typename_param_k H, ss_typename_param_k S>
  462. static class_type create_key(H const& key, S const& subKeyName, REGSAM accessMask = KEY_ALL_ACCESS)
  463. {
  464. return create_key_(get_HKEY(key), stlsoft_ns_qual(c_str_ptr)(subKeyName), accessMask);
  465. }
  466. #endif /* STLSOFT_CF_MEMBER_TEMPLATE_FUNCTION_SUPPORT */
  467. /** Deletes the named sub-key of this key
  468. *
  469. * \param subKeyName The name of the sub-key to be deleted.
  470. *
  471. * \return Indicates whether the sub-key was deleted.
  472. * \retval true The sub-key existed and was successfully deleted.
  473. * \retval false The sub-key does not exist. (<b>Note</b>:
  474. * if \ref page__exception_agnostic "exception handling is not enabled",
  475. * then false will also be returned for any other reason, and the
  476. * reason will be available via <code>::GetLastError()</code>.)
  477. *
  478. * \exception winstl::registry_exception If \ref page__exception_agnostic "exception handling is enabled",
  479. * an instance of \link winstl::registry_exception registry_exception\endlink
  480. * will be thrown if the sub-key exists but cannot be deleted.
  481. */
  482. bool_type delete_sub_key(char_type const* subKeyName);
  483. #ifdef STLSOFT_CF_MEMBER_TEMPLATE_FUNCTION_SUPPORT
  484. /** Deletes the named sub-key of this key
  485. *
  486. * \param subKeyName The name of the sub-key to be deleted.
  487. *
  488. * \return Indicates whether the sub-key was deleted.
  489. * \retval true The sub-key existed and was successfully deleted.
  490. * \retval false The sub-key does not exist. (<b>Note</b>:
  491. * if \ref page__exception_agnostic "exception handling is not enabled",
  492. * then false will also be returned for any other reason, and the
  493. * reason will be available via <code>::GetLastError()</code>.)
  494. *
  495. * \exception winstl::registry_exception If \ref page__exception_agnostic "exception handling is enabled",
  496. * an instance of \link winstl::registry_exception registry_exception\endlink
  497. * will be thrown if the sub-key exists but cannot be deleted.
  498. */
  499. template <ss_typename_param_k S>
  500. class_type delete_sub_key(S const& subKeyName)
  501. {
  502. return delete_sub_key_(stlsoft_ns_qual(c_str_ptr)(subKeyName));
  503. }
  504. #endif /* STLSOFT_CF_MEMBER_TEMPLATE_FUNCTION_SUPPORT */
  505. /// @}
  506. /// Returns a duplicate of the key's handle, if any.
  507. ///
  508. /// \param accessMask The access mask for the
  509. /// \param res A pointer to a variable (of type result_type) into
  510. /// which will be written the result of the underlying registry API
  511. /// call.
  512. ///
  513. /// \return
  514. ///
  515. /// \note The handle returned from this method <b>must</b> be closed with RegCloseKey()
  516. hkey_type dup_key_handle( REGSAM accessMask = KEY_ALL_ACCESS
  517. , result_type *res = NULL);
  518. /// \name Value operations
  519. /// @{
  520. public:
  521. /** Sets the named value to the value of the given 32-bit integer.
  522. *
  523. * \exception winstl::registry_exception If \ref page__exception_agnostic "exception handling is enabled",
  524. * an instance of \link winstl::registry_exception registry_exception\endlink
  525. * will be thrown if the value cannot be set.
  526. */
  527. bool_type set_value(char_type const* valueName, DWORD value);
  528. #ifdef STLSOFT_CF_64BIT_INT_SUPPORT
  529. /** Sets the named value to the value of the given 64-bit integer.
  530. *
  531. * \exception winstl::registry_exception If \ref page__exception_agnostic "exception handling is enabled",
  532. * an instance of \link winstl::registry_exception registry_exception\endlink
  533. * will be thrown if the value cannot be set.
  534. */
  535. bool_type set_value(char_type const* valueName, ws_uint64_t value);
  536. #endif /* STLSOFT_CF_64BIT_INT_SUPPORT */
  537. /** Sets the named value to the value of the given string.
  538. ///
  539. /// \param valueName The name of the value.
  540. /// \param value The value of the value
  541. /// \param type The type of the value. Must be one of REG_SZ, REG_EXPAND_SZ or REG_MULTI_SZ.
  542. *
  543. * \exception winstl::registry_exception If \ref page__exception_agnostic "exception handling is enabled",
  544. * an instance of \link winstl::registry_exception registry_exception\endlink
  545. * will be thrown if the value cannot be set.
  546. */
  547. bool_type set_value(char_type const* valueName, char_type const* value, ws_uint_t type = REG_SZ);
  548. /** Sets the named value to the values of the given string array.
  549. ///
  550. /// \param valueName The name of the value.
  551. /// \param values The string array.
  552. /// \param numValues Number of elements in the string array.
  553. *
  554. * \exception winstl::registry_exception If \ref page__exception_agnostic "exception handling is enabled",
  555. * an instance of \link winstl::registry_exception registry_exception\endlink
  556. * will be thrown if the value cannot be set.
  557. */
  558. bool_type set_value(char_type const* valueName, char_type const* const* values, size_type numValues);
  559. /** Sets the named value to the given binary value.
  560. *
  561. * \exception winstl::registry_exception If \ref page__exception_agnostic "exception handling is enabled",
  562. * an instance of \link winstl::registry_exception registry_exception\endlink
  563. * will be thrown if the value cannot be set.
  564. */
  565. bool_type set_value(char_type const* valueName, void const* value, size_type cbValue);
  566. #ifdef STLSOFT_CF_MEMBER_TEMPLATE_FUNCTION_SUPPORT
  567. /** Sets the named value to the value of the given 32-bit integer.
  568. *
  569. * \exception winstl::registry_exception If \ref page__exception_agnostic "exception handling is enabled",
  570. * an instance of \link winstl::registry_exception registry_exception\endlink
  571. * will be thrown if the value cannot be set.
  572. */
  573. template <ss_typename_param_k S>
  574. bool_type set_value(S const& valueName, DWORD value)
  575. {
  576. return set_value_(stlsoft_ns_qual(c_str_ptr)(valueName), value);
  577. }
  578. #endif /* STLSOFT_CF_MEMBER_TEMPLATE_FUNCTION_SUPPORT */
  579. #ifdef STLSOFT_CF_64BIT_INT_SUPPORT
  580. # ifdef STLSOFT_CF_MEMBER_TEMPLATE_FUNCTION_SUPPORT
  581. /** Sets the named value to the value of the given 64-bit integer.
  582. *
  583. * \exception winstl::registry_exception If \ref page__exception_agnostic "exception handling is enabled",
  584. * an instance of \link winstl::registry_exception registry_exception\endlink
  585. * will be thrown if the value cannot be set.
  586. */
  587. template <ss_typename_param_k S>
  588. bool_type set_value(S const& valueName, ws_uint64_t value)
  589. {
  590. return set_value_(stlsoft_ns_qual(c_str_ptr)(valueName), value);
  591. }
  592. # endif /* STLSOFT_CF_MEMBER_TEMPLATE_FUNCTION_SUPPORT */
  593. #endif /* STLSOFT_CF_64BIT_INT_SUPPORT */
  594. #ifdef STLSOFT_CF_MEMBER_TEMPLATE_FUNCTION_SUPPORT
  595. /** Sets the named value to the value of the given string.
  596. ///
  597. /// \param valueName The name of the value.
  598. /// \param value The value of the value
  599. /// \param type The type of the value. Must be one of REG_SZ, REG_EXPAND_SZ or REG_MULTI_SZ.
  600. *
  601. * \exception winstl::registry_exception If \ref page__exception_agnostic "exception handling is enabled",
  602. * an instance of \link winstl::registry_exception registry_exception\endlink
  603. * will be thrown if the value cannot be set.
  604. */
  605. template <ss_typename_param_k S>
  606. bool_type set_value(S const& valueName, char_type const* value, ws_uint_t type = REG_SZ)
  607. {
  608. return set_value_(stlsoft_ns_qual(c_str_ptr)(valueName), value, type);
  609. }
  610. #endif /* STLSOFT_CF_MEMBER_TEMPLATE_FUNCTION_SUPPORT */
  611. #ifdef STLSOFT_CF_MEMBER_TEMPLATE_FUNCTION_SUPPORT
  612. /** Sets the named value to the values of the given string array.
  613. ///
  614. /// \param valueName The name of the value.
  615. /// \param values The string array.
  616. /// \param numValues Number of elements in the string array.
  617. *
  618. * \exception winstl::registry_exception If \ref page__exception_agnostic "exception handling is enabled",
  619. * an instance of \link winstl::registry_exception registry_exception\endlink
  620. * will be thrown if the value cannot be set.
  621. */
  622. template <ss_typename_param_k S>
  623. bool_type set_value(S const& valueName, char_type const* const* values, size_type numValues)
  624. {
  625. return set_value_(stlsoft_ns_qual(c_str_ptr)(valueName), values, numValues);
  626. }
  627. #endif /* STLSOFT_CF_MEMBER_TEMPLATE_FUNCTION_SUPPORT */
  628. #ifdef STLSOFT_CF_MEMBER_TEMPLATE_FUNCTION_SUPPORT
  629. /** Sets the named value to the given binary value.
  630. *
  631. * \exception winstl::registry_exception If \ref page__exception_agnostic "exception handling is enabled",
  632. * an instance of \link winstl::registry_exception registry_exception\endlink
  633. * will be thrown if the value cannot be set.
  634. */
  635. template <ss_typename_param_k S>
  636. bool_type set_value(S const& valueName, void const* value, size_type cbValue)
  637. {
  638. return set_value_(stlsoft_ns_qual(c_str_ptr)(valueName), value, cbValue);
  639. }
  640. #endif /* STLSOFT_CF_MEMBER_TEMPLATE_FUNCTION_SUPPORT */
  641. /** Sets the named value to the given integer (stored as an unsigned value).
  642. ///
  643. /// \note This method is provided solely to disambiguate between the DWORD and ws_uint64_t overloads
  644. /// when using integer literals.
  645. *
  646. * \exception winstl::registry_exception If \ref page__exception_agnostic "exception handling is enabled",
  647. * an instance of \link winstl::registry_exception registry_exception\endlink
  648. * will be thrown if the value cannot be set.
  649. */
  650. bool_type set_value(char_type const* valueName, int value);
  651. #ifdef STLSOFT_CF_MEMBER_TEMPLATE_FUNCTION_SUPPORT
  652. /** Sets the named value to the given integer (stored as an unsigned value).
  653. ///
  654. /// \note This method is provided solely to disambiguate between the DWORD and ws_uint64_t overloads
  655. /// when using integer literals.
  656. *
  657. * \exception winstl::registry_exception If \ref page__exception_agnostic "exception handling is enabled",
  658. * an instance of \link winstl::registry_exception registry_exception\endlink
  659. * will be thrown if the value cannot be set.
  660. */
  661. template <ss_typename_param_k S>
  662. bool_type set_value(S const& valueName, int value)
  663. {
  664. return set_value_(stlsoft_ns_qual(c_str_ptr)(valueName), value);
  665. }
  666. #endif /* STLSOFT_CF_MEMBER_TEMPLATE_FUNCTION_SUPPORT */
  667. /** Deletes the named value.
  668. *
  669. * \param valueName The name of the value to be deleted.
  670. *
  671. * \return Indicates whether the value was deleted.
  672. * \retval true The value existed and was successfully deleted.
  673. * \retval false The value does not exist. (<b>Note</b>:
  674. * if \ref page__exception_agnostic "exception handling is not enabled",
  675. * then false will also be returned for any other reason, and the
  676. * reason will be available via <code>::GetLastError()</code>.)
  677. *
  678. * \exception winstl::registry_exception If \ref page__exception_agnostic "exception handling is enabled",
  679. * an instance of \link winstl::registry_exception registry_exception\endlink
  680. * will be thrown if the value exists but cannot be deleted.
  681. */
  682. bool_type delete_value(char_type const* valueName);
  683. #ifdef STLSOFT_CF_MEMBER_TEMPLATE_FUNCTION_SUPPORT
  684. /** Deletes the named value.
  685. *
  686. * \param valueName The name of the value to be deleted.
  687. *
  688. * \return Indicates whether the value was deleted.
  689. * \retval true The value existed and was successfully deleted.
  690. * \retval false The value does not exist. (<b>Note</b>:
  691. * if \ref page__exception_agnostic "exception handling is not enabled",
  692. * then false will also be returned for any other reason, and the
  693. * reason will be available via <code>::GetLastError()</code>.)
  694. *
  695. * \exception winstl::registry_exception If \ref page__exception_agnostic "exception handling is enabled",
  696. * an instance of \link winstl::registry_exception registry_exception\endlink
  697. * will be thrown if the value exists but cannot be deleted.
  698. */
  699. template <ss_typename_param_k S>
  700. bool_type delete_value(S const& valueName)
  701. {
  702. return this->delete_value_(stlsoft_ns_qual(c_str_ptr)(valueName));
  703. }
  704. #endif /* STLSOFT_CF_MEMBER_TEMPLATE_FUNCTION_SUPPORT */
  705. #if 0
  706. ws_dword_t get_value_type(char_type const* valueName) const;
  707. size_type get_value_data_size(char_type const* valueName) const;
  708. #endif /* 0 */
  709. /** Returns the named value.
  710. ///
  711. /// \return An instance of basic_reg_value.
  712. */
  713. key_value_type get_value(char_type const* valueName) const;
  714. #ifdef STLSOFT_CF_MEMBER_TEMPLATE_FUNCTION_SUPPORT
  715. /** Returns the named value.
  716. ///
  717. /// \return An instance of basic_reg_value.
  718. */
  719. template <ss_typename_param_k S>
  720. key_value_type get_value(S const& valueName) const
  721. {
  722. return this->get_value(stlsoft_ns_qual(c_str_ptr)(stlsoft_ns_qual(c_str_ptr)(valueName)));
  723. }
  724. #endif /* STLSOFT_CF_MEMBER_TEMPLATE_FUNCTION_SUPPORT */
  725. // std::list<key_value_type> get_values(char_type const* valueNames) const;
  726. /// @}
  727. /// \name Implementation
  728. /// @{
  729. private:
  730. static hkey_type open_key_( hkey_type hkeyParent
  731. , char_type const* keyName
  732. , REGSAM accessMask);
  733. class_type open_sub_key_( char_type const* subKeyName
  734. , REGSAM accessMask);
  735. static class_type create_key_( HKEY hkey
  736. , char_type const* subKeyName
  737. , REGSAM accessMask);
  738. class_type create_sub_key_( char_type const* subKeyName
  739. , REGSAM accessMask);
  740. bool_type delete_sub_key_( char_type const* subKeyName);
  741. static result_type set_value_( hkey_type hkey
  742. , char_type const* valueName
  743. , ws_uint_t type
  744. , void const* value
  745. , size_type cbValue);
  746. bool_type set_value_int_(char_type const* valueName, int value, stlsoft_ns_qual(yes_type));
  747. bool_type set_value_int_(char_type const* valueName, int value, stlsoft_ns_qual(no_type));
  748. bool_type set_value_(char_type const* valueName, DWORD value);
  749. # ifdef STLSOFT_CF_64BIT_INT_SUPPORT
  750. bool_type set_value_(char_type const* valueName, ws_uint64_t value);
  751. # endif /* STLSOFT_CF_64BIT_INT_SUPPORT */
  752. bool_type set_value_(char_type const* valueName, char_type const* value, ws_uint_t type);
  753. bool_type set_value_(char_type const* valueName, char_type const* const* values, size_type numValues);
  754. bool_type set_value_(char_type const* valueName, void const* value, size_type cbValue);
  755. bool_type set_value_(char_type const* valueName, int value);
  756. bool_type delete_value_(char_type const* valueName);
  757. bool_type has_sub_key_(char_type const* subKeyName);
  758. bool_type has_value_(char_type const* valueName);
  759. static result_type get_value_(hkey_type hkey, char_type const* valueName, ws_uint_t type, void *value, size_type *pcbValue);
  760. static hkey_type dup_key_( hkey_type hkey
  761. , REGSAM accessMask = KEY_ALL_ACCESS);
  762. /// @}
  763. /// \name Operations
  764. /// @{
  765. public:
  766. /** Efficiently swaps the contents between two instances
  767. ///
  768. /// \param rhs The parameter whose contents will be swapped.
  769. */
  770. void swap(class_type& rhs) stlsoft_throw_0();
  771. /// @}
  772. /// \name Members
  773. /// @{
  774. private:
  775. string_type m_name; // The key name
  776. hkey_type m_hkey; // The key handle
  777. REGSAM m_accessMask; // The security access mask
  778. /// @}
  779. };
  780. /* Typedefs to commonly encountered types. */
  781. /** Specialisation of the basic_reg_key template for the ANSI character type \c char
  782. *
  783. * \ingroup group__library__windows_registry
  784. */
  785. typedef basic_reg_key<ws_char_a_t, reg_traits<ws_char_a_t>, processheap_allocator<ws_char_a_t> > reg_key_a;
  786. /** Specialisation of the basic_reg_key template for the Unicode character type \c wchar_t
  787. *
  788. * \ingroup group__library__windows_registry
  789. */
  790. typedef basic_reg_key<ws_char_w_t, reg_traits<ws_char_w_t>, processheap_allocator<ws_char_w_t> > reg_key_w;
  791. /** Specialisation of the basic_reg_key template for the Win32 character type \c TCHAR
  792. *
  793. * \ingroup group__library__windows_registry
  794. */
  795. typedef basic_reg_key<TCHAR, reg_traits<TCHAR>, processheap_allocator<TCHAR> > reg_key;
  796. /* /////////////////////////////////////////////////////////////////////////
  797. * Handle access shims
  798. */
  799. /* get_handle */
  800. /** [\ref group__concept__shims "Shim" function] Returns the corresponding registry handle of an instance of winstl::basic_reg_key basic_reg_key.
  801. *
  802. * \ingroup group__library__windows_registry
  803. *
  804. * \param key The \link winstl::basic_reg_key basic_reg_key\endlink instance.
  805. *
  806. * \return The HKEY handle of the given \link winstl::basic_reg_key basic_reg_key\endlink instance.
  807. */
  808. template< ss_typename_param_k C
  809. , ss_typename_param_k T
  810. , ss_typename_param_k A
  811. >
  812. inline HKEY get_handle(basic_reg_key<C, T, A> const& key)
  813. {
  814. return key.get_key_handle();
  815. }
  816. /** [\ref group__concept__shims "Shim" function] Returns the corresponding registry handle of an instance of winstl::basic_reg_key basic_reg_key.
  817. *
  818. * \ingroup group__library__shims__hkey_attribute
  819. *
  820. * This access <a href = "http://stlsoft.org/white_papers.html#shims">shim</a>
  821. * retrieves the HKEY registry handle for the given HKEY handle.
  822. *
  823. * \param key The winstl::basic_reg_key basic_reg_key instance whose corresponding HKEY will be retrieved
  824. *
  825. * \return The HKEY handle of the given winstl::basic_reg_key basic_reg_key instance
  826. */
  827. template< ss_typename_param_k C
  828. , ss_typename_param_k T
  829. , ss_typename_param_k A
  830. >
  831. inline HKEY get_HKEY(basic_reg_key<C, T, A> const& key)
  832. {
  833. return key.get_key_handle();
  834. }
  835. ////////////////////////////////////////////////////////////////////////////
  836. // Unit-testing
  837. #ifdef STLSOFT_UNITTEST
  838. # include "./unittest/reg_key_unittest_.h"
  839. #endif /* STLSOFT_UNITTEST */
  840. /* /////////////////////////////////////////////////////////////////////////
  841. * Implementation
  842. */
  843. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  844. template< ss_typename_param_k C
  845. , ss_typename_param_k T
  846. , ss_typename_param_k A
  847. >
  848. #if ( defined(STLSOFT_COMPILER_IS_MSVC) && \
  849. _MSC_VER < 1100) || \
  850. defined(STLSOFT_COMPILER_IS_VECTORC)
  851. inline /* static */ ss_typename_type_ret_k basic_reg_key<C, T, A>::hkey_type basic_reg_key<C, T, A>::open_key_(hkey_type hkeyParent, char_type const* keyName, REGSAM accessMask)
  852. #else /* ? compiler */
  853. inline /* static */ ss_typename_type_ret_k basic_reg_key<C, T, A>::hkey_type basic_reg_key<C, T, A>::open_key_(ss_typename_param_k basic_reg_key<C, T, A>::hkey_type hkeyParent, ss_typename_param_k basic_reg_key<C, T, A>::char_type const* keyName, REGSAM accessMask)
  854. #endif /* compiler */
  855. {
  856. hkey_type hkey;
  857. result_type res = traits_type::reg_open_key(hkeyParent, keyName, &hkey, accessMask);
  858. if(ERROR_SUCCESS != res)
  859. {
  860. #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
  861. static const char message[] = "could not open key";
  862. if(ERROR_ACCESS_DENIED == res)
  863. {
  864. STLSOFT_THROW_X(access_denied_exception(message, res));
  865. }
  866. else
  867. {
  868. STLSOFT_THROW_X(registry_exception(message, res));
  869. }
  870. #else /* ? STLSOFT_CF_EXCEPTION_SUPPORT */
  871. ::SetLastError(res);
  872. hkey = NULL;
  873. #endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
  874. }
  875. return hkey;
  876. }
  877. template< ss_typename_param_k C
  878. , ss_typename_param_k T
  879. , ss_typename_param_k A
  880. >
  881. inline /* static */ ss_typename_type_ret_k basic_reg_key<C, T, A>::hkey_type basic_reg_key<C, T, A>::dup_key_( ss_typename_type_k basic_reg_key<C, T, A>::hkey_type hkey
  882. , REGSAM accessMask /* = KEY_ALL_ACCESS */)
  883. {
  884. if(NULL == hkey)
  885. {
  886. return NULL;
  887. }
  888. else
  889. {
  890. result_type res;
  891. HKEY hkeyDup = traits_type::key_dup(hkey, accessMask, &res);
  892. if(ERROR_SUCCESS != res)
  893. {
  894. #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
  895. static const char message[] = "could not duplicate key";
  896. if(ERROR_ACCESS_DENIED == res)
  897. {
  898. STLSOFT_THROW_X(access_denied_exception(message, res));
  899. }
  900. else
  901. {
  902. STLSOFT_THROW_X(key_not_duplicated_exception(message, res));
  903. }
  904. #else /* ? STLSOFT_CF_EXCEPTION_SUPPORT */
  905. ::SetLastError(res);
  906. hkeyDup = NULL;
  907. #endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
  908. }
  909. return hkeyDup;
  910. }
  911. }
  912. // Construction
  913. template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
  914. inline basic_reg_key<C, T, A>::basic_reg_key()
  915. : m_name()
  916. , m_hkey(NULL)
  917. , m_accessMask(KEY_READ)
  918. {}
  919. template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
  920. inline basic_reg_key<C, T, A>::basic_reg_key(ss_typename_type_k basic_reg_key<C, T, A>::hkey_type* hkey, ss_typename_type_k basic_reg_key<C, T, A>::string_type const& keyName, REGSAM accessMask)
  921. : m_name(keyName)
  922. , m_hkey(*hkey)
  923. , m_accessMask(accessMask)
  924. {}
  925. template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
  926. inline basic_reg_key<C, T, A>::basic_reg_key(class_type const& rhs)
  927. : m_name(rhs.m_name)
  928. , m_hkey(dup_key_(rhs.m_hkey, rhs.get_access_mask()))
  929. , m_accessMask(rhs.m_accessMask)
  930. {}
  931. template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
  932. inline basic_reg_key<C, T, A>::basic_reg_key(class_type const& rhs, REGSAM accessMask)
  933. : m_name(rhs.m_name)
  934. , m_hkey(dup_key_(rhs.m_hkey, accessMask))
  935. , m_accessMask(accessMask)
  936. {}
  937. template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
  938. inline basic_reg_key<C, T, A>::~basic_reg_key() stlsoft_throw_0()
  939. {
  940. if(m_hkey != NULL)
  941. {
  942. ::RegCloseKey(m_hkey);
  943. }
  944. }
  945. template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
  946. inline void basic_reg_key<C, T, A>::swap(ss_typename_type_k basic_reg_key<C, T, A>::class_type& rhs) stlsoft_throw_0()
  947. {
  948. std_swap(m_name, rhs.m_name);
  949. std_swap(m_hkey, rhs.m_hkey);
  950. std_swap(m_accessMask, rhs.m_accessMask);
  951. }
  952. template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
  953. inline ss_typename_type_ret_k basic_reg_key<C, T, A>::class_type& basic_reg_key<C, T, A>::operator =(ss_typename_type_k basic_reg_key<C, T, A>::class_type const& rhs)
  954. {
  955. class_type _this(rhs);
  956. swap(_this);
  957. return *this;
  958. }
  959. // Attributes
  960. template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
  961. inline ss_typename_type_ret_k basic_reg_key<C, T, A>::string_type const& basic_reg_key<C, T, A>::name() const
  962. {
  963. return m_name;
  964. }
  965. template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
  966. inline ss_typename_type_ret_k basic_reg_key<C, T, A>::string_type basic_reg_key<C, T, A>::reg_class() const
  967. {
  968. size_type cch_key_class = 0;
  969. ws_long_t res = traits_type::reg_query_info(m_hkey, NULL, &cch_key_class, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
  970. if(ERROR_SUCCESS != res)
  971. {
  972. #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
  973. query_fail:
  974. static const char message[] = "could not determine the key registry class";
  975. if(ERROR_ACCESS_DENIED == res)
  976. {
  977. STLSOFT_THROW_X(access_denied_exception(message, res));
  978. }
  979. else
  980. {
  981. STLSOFT_THROW_X(registry_exception(message, res));
  982. }
  983. #endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
  984. }
  985. else
  986. {
  987. stlsoft_ns_qual(auto_buffer_old)<char_type, allocator_type, CCH_REG_API_AUTO_BUFFER> p(++cch_key_class);
  988. res = traits_type::reg_query_info(m_hkey, &p[0], &cch_key_class, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
  989. if(ERROR_SUCCESS != res)
  990. {
  991. #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
  992. goto query_fail;
  993. #endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
  994. }
  995. else
  996. {
  997. return string_type(&p[0], cch_key_class);
  998. }
  999. }
  1000. return string_type();
  1001. }
  1002. template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
  1003. inline ss_typename_type_ret_k basic_reg_key<C, T, A>::size_type basic_reg_key<C, T, A>::num_sub_keys() const
  1004. {
  1005. ws_uint32_t c_sub_keys;
  1006. ws_long_t res = traits_type::reg_query_info(m_hkey, NULL, NULL, &c_sub_keys, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
  1007. if(ERROR_SUCCESS != res)
  1008. {
  1009. #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
  1010. static const char message[] = "could not determine the number of sub-keys";
  1011. if(ERROR_ACCESS_DENIED == res)
  1012. {
  1013. STLSOFT_THROW_X(access_denied_exception(message, res));
  1014. }
  1015. else
  1016. {
  1017. STLSOFT_THROW_X(registry_exception(message, res));
  1018. }
  1019. #else /* ? STLSOFT_CF_EXCEPTION_SUPPORT */
  1020. c_sub_keys = 0;
  1021. #endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
  1022. }
  1023. return c_sub_keys;
  1024. }
  1025. template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
  1026. inline ss_typename_type_ret_k basic_reg_key<C, T, A>::size_type basic_reg_key<C, T, A>::num_values() const
  1027. {
  1028. ws_uint32_t c_values;
  1029. ws_long_t res = traits_type::reg_query_info(m_hkey, NULL, NULL, NULL, NULL, NULL, &c_values, NULL, NULL, NULL, NULL);
  1030. if(ERROR_SUCCESS != res)
  1031. {
  1032. #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
  1033. static const char message[] = "could not determine the number of values";
  1034. if(ERROR_ACCESS_DENIED == res)
  1035. {
  1036. STLSOFT_THROW_X(access_denied_exception(message, res));
  1037. }
  1038. else
  1039. {
  1040. STLSOFT_THROW_X(registry_exception(message, res));
  1041. }
  1042. #else /* ? STLSOFT_CF_EXCEPTION_SUPPORT */
  1043. c_values = 0;
  1044. #endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
  1045. }
  1046. return c_values;
  1047. }
  1048. template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
  1049. inline ss_typename_type_ret_k basic_reg_key<C, T, A>::hkey_type basic_reg_key<C, T, A>::get_key_handle() const
  1050. {
  1051. return m_hkey;
  1052. }
  1053. template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
  1054. inline ss_typename_type_ret_k basic_reg_key<C, T, A>::hkey_type basic_reg_key<C, T, A>::get() const
  1055. {
  1056. return get_key_handle();
  1057. }
  1058. template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
  1059. inline REGSAM basic_reg_key<C, T, A>::get_access_mask() const
  1060. {
  1061. return m_accessMask;
  1062. }
  1063. // Operations
  1064. template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
  1065. inline ss_typename_type_ret_k basic_reg_key<C, T, A>::class_type basic_reg_key<C, T, A>::open_sub_key(char_type const* subKeyName, REGSAM accessMask /* = KEY_ALL_ACCESS */)
  1066. {
  1067. return this->open_sub_key_(subKeyName, accessMask);
  1068. }
  1069. template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
  1070. inline ss_typename_type_ret_k basic_reg_key<C, T, A>::class_type basic_reg_key<C, T, A>::create_sub_key(char_type const* subKeyName, REGSAM accessMask /* = KEY_ALL_ACCESS */)
  1071. {
  1072. return this->create_sub_key_(subKeyName, accessMask);
  1073. }
  1074. template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
  1075. inline /* static */ ss_typename_type_ret_k basic_reg_key<C, T, A>::class_type basic_reg_key<C, T, A>::create_key(HKEY hkey, char_type const* subKeyName, REGSAM accessMask /* = KEY_ALL_ACCESS */)
  1076. {
  1077. return create_key_(hkey, subKeyName, accessMask);
  1078. }
  1079. template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
  1080. inline ss_typename_type_ret_k basic_reg_key<C, T, A>::class_type basic_reg_key<C, T, A>::open_sub_key_(char_type const* subKeyName, REGSAM accessMask /* = KEY_ALL_ACCESS */)
  1081. {
  1082. return class_type(m_hkey, subKeyName, accessMask);
  1083. }
  1084. template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
  1085. inline /* static */ ss_typename_type_ret_k basic_reg_key<C, T, A>::class_type basic_reg_key<C, T, A>::create_key_(
  1086. HKEY hkey
  1087. , char_type const* subKeyName
  1088. , REGSAM accessMask
  1089. )
  1090. {
  1091. static const char_type s_emptyString[] = { '\0' };
  1092. return class_type(hkey, s_emptyString, KEY_CREATE_SUB_KEY).create_sub_key(subKeyName, accessMask);
  1093. }
  1094. template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
  1095. inline ss_typename_type_ret_k basic_reg_key<C, T, A>::class_type basic_reg_key<C, T, A>::create_sub_key_(
  1096. char_type const* subKeyName
  1097. , REGSAM accessMask
  1098. )
  1099. {
  1100. hkey_type hkey;
  1101. result_type res = traits_type::reg_create_key(m_hkey, subKeyName, &hkey, accessMask);
  1102. if(ERROR_SUCCESS != res)
  1103. {
  1104. #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
  1105. static const char message[] = "could not create sub-key";
  1106. if(ERROR_ACCESS_DENIED == res)
  1107. {
  1108. STLSOFT_THROW_X(access_denied_exception(message, res));
  1109. }
  1110. else
  1111. {
  1112. STLSOFT_THROW_X(registry_exception(message, res));
  1113. }
  1114. #else /* ? STLSOFT_CF_EXCEPTION_SUPPORT */
  1115. ::SetLastError(res);
  1116. return class_type();
  1117. #endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
  1118. }
  1119. return class_type(&hkey, subKeyName, accessMask);
  1120. }
  1121. template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
  1122. inline ss_typename_type_ret_k basic_reg_key<C, T, A>::bool_type basic_reg_key<C, T, A>::delete_sub_key(char_type const* subKeyName)
  1123. {
  1124. return this->delete_sub_key_(subKeyName);
  1125. }
  1126. template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
  1127. inline ss_typename_type_ret_k basic_reg_key<C, T, A>::bool_type basic_reg_key<C, T, A>::delete_sub_key_(char_type const* subKeyName)
  1128. {
  1129. #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
  1130. static const char message[] = "could not delete sub-key";
  1131. #endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
  1132. result_type res = traits_type::reg_delete_key(m_hkey, subKeyName);
  1133. switch(res)
  1134. {
  1135. case ERROR_SUCCESS:
  1136. return true;
  1137. default:
  1138. #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
  1139. if(ERROR_ACCESS_DENIED == res)
  1140. {
  1141. STLSOFT_THROW_X(access_denied_exception(message, res));
  1142. }
  1143. else
  1144. {
  1145. STLSOFT_THROW_X(registry_exception(message, res));
  1146. }
  1147. #else /* ? STLSOFT_CF_EXCEPTION_SUPPORT */
  1148. ::SetLastError(res);
  1149. // Fall through
  1150. #endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
  1151. case ERROR_FILE_NOT_FOUND:
  1152. return false;
  1153. }
  1154. }
  1155. /* The handle returned from this method MUST be closed with RegCloseKey() */
  1156. template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
  1157. inline ss_typename_type_ret_k basic_reg_key<C, T, A>::hkey_type basic_reg_key<C, T, A>::dup_key_handle(REGSAM accessMask /* = KEY_ALL_ACCESS */, result_type *res /* = NULL */)
  1158. {
  1159. return traits_type::key_dup(m_hkey, accessMask, res);
  1160. }
  1161. // Values
  1162. template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
  1163. inline ss_typename_type_ret_k basic_reg_key<C, T, A>::bool_type basic_reg_key<C, T, A>::set_value(ss_typename_type_k basic_reg_key<C, T, A>::char_type const* valueName, DWORD value)
  1164. {
  1165. return set_value_(valueName, value);
  1166. }
  1167. # ifdef STLSOFT_CF_64BIT_INT_SUPPORT
  1168. template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
  1169. inline ss_typename_type_ret_k basic_reg_key<C, T, A>::bool_type basic_reg_key<C, T, A>::set_value(ss_typename_type_k basic_reg_key<C, T, A>::char_type const* valueName, ws_uint64_t value)
  1170. {
  1171. return set_value_(valueName, value);
  1172. }
  1173. # endif /* STLSOFT_CF_64BIT_INT_SUPPORT */
  1174. template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
  1175. inline ss_typename_type_ret_k basic_reg_key<C, T, A>::bool_type basic_reg_key<C, T, A>::set_value(ss_typename_type_k basic_reg_key<C, T, A>::char_type const* valueName, int value)
  1176. {
  1177. return set_value_(valueName, value);
  1178. }
  1179. template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
  1180. inline ss_typename_type_ret_k basic_reg_key<C, T, A>::bool_type basic_reg_key<C, T, A>::set_value(ss_typename_type_k basic_reg_key<C, T, A>::char_type const* valueName, char_type const* value, ws_uint_t type /* = REG_SZ */)
  1181. {
  1182. return set_value_(valueName, value, type);
  1183. }
  1184. template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
  1185. inline ss_typename_type_ret_k basic_reg_key<C, T, A>::bool_type basic_reg_key<C, T, A>::set_value(ss_typename_type_k basic_reg_key<C, T, A>::char_type const* valueName, ss_typename_type_k basic_reg_key<C, T, A>::char_type const* const* values, ss_typename_type_k basic_reg_key<C, T, A>::size_type numValues)
  1186. {
  1187. return set_value_(valueName, values, numValues);
  1188. }
  1189. template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
  1190. inline ss_typename_type_ret_k basic_reg_key<C, T, A>::bool_type basic_reg_key<C, T, A>::set_value(ss_typename_type_k basic_reg_key<C, T, A>::char_type const* valueName, void const* value, size_type cbValue)
  1191. {
  1192. return set_value_(valueName, value, cbValue);
  1193. }
  1194. template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
  1195. inline /* static */ ss_typename_type_ret_k basic_reg_key<C, T, A>::result_type basic_reg_key<C, T, A>::set_value_( ss_typename_type_k basic_reg_key<C, T, A>::hkey_type hkey
  1196. , ss_typename_type_k basic_reg_key<C, T, A>::char_type const *valueName
  1197. , ws_uint_t type
  1198. , void const *value
  1199. , ss_typename_type_k basic_reg_key<C, T, A>::size_type cbValue)
  1200. {
  1201. result_type res = traits_type::reg_set_value(hkey, valueName, type, value, cbValue);
  1202. #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
  1203. if(ERROR_SUCCESS != res)
  1204. {
  1205. static const char message[] = "could not create value";
  1206. if(ERROR_ACCESS_DENIED == res)
  1207. {
  1208. STLSOFT_THROW_X(access_denied_exception(message, res));
  1209. }
  1210. else
  1211. {
  1212. STLSOFT_THROW_X(registry_exception(message, res));
  1213. }
  1214. }
  1215. #endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
  1216. return res;
  1217. }
  1218. template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
  1219. inline ss_typename_type_ret_k basic_reg_key<C, T, A>::bool_type basic_reg_key<C, T, A>::set_value_(ss_typename_type_k basic_reg_key<C, T, A>::char_type const* valueName, DWORD value)
  1220. {
  1221. return ERROR_SUCCESS == class_type::set_value_(m_hkey, valueName, REG_DWORD, &value, sizeof(value));
  1222. }
  1223. # ifdef STLSOFT_CF_64BIT_INT_SUPPORT
  1224. template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
  1225. inline ss_typename_type_ret_k basic_reg_key<C, T, A>::bool_type basic_reg_key<C, T, A>::set_value_(ss_typename_type_k basic_reg_key<C, T, A>::char_type const* valueName, ws_uint64_t value)
  1226. {
  1227. #ifndef REG_QWORD
  1228. const DWORD REG_QWORD = 11;
  1229. #endif /* !REG_QWORD */
  1230. return ERROR_SUCCESS == class_type::set_value_(m_hkey, valueName, REG_QWORD, &value, sizeof(value));
  1231. }
  1232. # endif /* STLSOFT_CF_64BIT_INT_SUPPORT */
  1233. template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
  1234. inline ss_typename_type_ret_k basic_reg_key<C, T, A>::bool_type basic_reg_key<C, T, A>::set_value_(ss_typename_type_k basic_reg_key<C, T, A>::char_type const* valueName, char_type const* value, ws_uint_t type /* = REG_SZ */)
  1235. {
  1236. WINSTL_ASSERT(REG_SZ == type || REG_EXPAND_SZ == type || REG_MULTI_SZ == type);
  1237. return ERROR_SUCCESS == class_type::set_value_(m_hkey, valueName, type, value, traits_type::str_len(value) * sizeof(char_type));
  1238. }
  1239. template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
  1240. inline ss_typename_type_ret_k basic_reg_key<C, T, A>::bool_type basic_reg_key<C, T, A>::set_value_(ss_typename_type_k basic_reg_key<C, T, A>::char_type const* valueName, ss_typename_type_k basic_reg_key<C, T, A>::char_type const* const* values, ss_typename_type_k basic_reg_key<C, T, A>::size_type numValues)
  1241. {
  1242. // Evaluate the total length of the source values
  1243. const size_type totalLen = winstl_ns_qual_std(accumulate)( stlsoft_ns_qual(transformer)(values, std::ptr_fun(traits_type::str_len))
  1244. , stlsoft_ns_qual(transformer)(values + numValues, std::ptr_fun(traits_type::str_len))
  1245. , size_type(0));
  1246. // Create a buffer of sufficient size: total length + a nul-terminator for each value + a double nul-terminator
  1247. stlsoft_ns_qual(auto_buffer)<char_type> buff(totalLen + numValues * 1 + 2);
  1248. if(buff.empty())
  1249. {
  1250. ::SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  1251. return false;
  1252. }
  1253. // Now synthesise all the data
  1254. char_type *p = &buff[0];
  1255. { for(size_type i = 0; i != numValues; ++i)
  1256. {
  1257. char_type const* const s = values[i];
  1258. const size_type len = traits_type::str_len(s);
  1259. ::memcpy(p, s, sizeof(char_type) * len);
  1260. p += len;
  1261. *p++ = '\0';
  1262. }}
  1263. *p++ = '\0';
  1264. *p++ = '\0';
  1265. return ERROR_SUCCESS == class_type::set_value_(m_hkey, valueName, REG_MULTI_SZ, buff.data(), static_cast<size_type>(p - &buff[0]) * sizeof(char_type));
  1266. }
  1267. template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
  1268. inline ss_typename_type_ret_k basic_reg_key<C, T, A>::bool_type basic_reg_key<C, T, A>::set_value_(ss_typename_type_k basic_reg_key<C, T, A>::char_type const* valueName, void const* value, size_type cbValue)
  1269. {
  1270. return ERROR_SUCCESS == class_type::set_value_(m_hkey, valueName, REG_BINARY, value, cbValue);
  1271. }
  1272. template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
  1273. inline ss_typename_type_ret_k basic_reg_key<C, T, A>::bool_type basic_reg_key<C, T, A>::set_value_int_(ss_typename_type_k basic_reg_key<C, T, A>::char_type const* valueName, int value, stlsoft_ns_qual(yes_type))
  1274. {
  1275. return this->set_value(valueName, static_cast<DWORD>(value));
  1276. }
  1277. template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
  1278. inline ss_typename_type_ret_k basic_reg_key<C, T, A>::bool_type basic_reg_key<C, T, A>::set_value_int_(ss_typename_type_k basic_reg_key<C, T, A>::char_type const* valueName, int value, stlsoft_ns_qual(no_type))
  1279. {
  1280. return this->set_value(valueName, static_cast<ws_uint64_t>(value));
  1281. }
  1282. template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
  1283. inline ss_typename_type_ret_k basic_reg_key<C, T, A>::bool_type basic_reg_key<C, T, A>::set_value_(ss_typename_type_k basic_reg_key<C, T, A>::char_type const* valueName, int value)
  1284. {
  1285. // Because Borland is quite dense, we must use two typedefs here,
  1286. // rather than just one
  1287. #if 0
  1288. typedef ss_typename_type_k stlsoft_ns_qual(value_to_yesno_type)<sizeof(int) <= sizeof(DWORD)>::type yesno_t;
  1289. #else /* ? 0 */
  1290. typedef stlsoft_ns_qual(value_to_yesno_type)<sizeof(int) <= sizeof(DWORD)> value_to_yesno_t;
  1291. typedef ss_typename_type_k value_to_yesno_t::type yesno_t;
  1292. #endif /* 0 */
  1293. return ERROR_SUCCESS == set_value_int_(valueName, value, yesno_t());
  1294. }
  1295. template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
  1296. inline ss_typename_type_ret_k basic_reg_key<C, T, A>::bool_type basic_reg_key<C, T, A>::delete_value(ss_typename_type_k basic_reg_key<C, T, A>::char_type const* valueName)
  1297. {
  1298. return this->delete_value_(valueName);
  1299. }
  1300. template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
  1301. inline ss_typename_type_ret_k basic_reg_key<C, T, A>::bool_type basic_reg_key<C, T, A>::delete_value_(ss_typename_type_k basic_reg_key<C, T, A>::char_type const* valueName)
  1302. {
  1303. #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
  1304. static const char message[] = "could not delete value";
  1305. #endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
  1306. result_type res = traits_type::reg_delete_value(m_hkey, valueName);
  1307. switch(res)
  1308. {
  1309. case ERROR_SUCCESS:
  1310. return true;
  1311. default:
  1312. #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
  1313. if(ERROR_ACCESS_DENIED == res)
  1314. {
  1315. STLSOFT_THROW_X(access_denied_exception(message, res));
  1316. }
  1317. else
  1318. {
  1319. STLSOFT_THROW_X(registry_exception(message, res));
  1320. }
  1321. #else /* ? STLSOFT_CF_EXCEPTION_SUPPORT */
  1322. ::SetLastError(res);
  1323. // Fall through
  1324. #endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
  1325. case ERROR_FILE_NOT_FOUND:
  1326. return false;
  1327. }
  1328. }
  1329. template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
  1330. inline ss_typename_type_ret_k basic_reg_key<C, T, A>::bool_type basic_reg_key<C, T, A>::has_sub_key_(ss_typename_type_k basic_reg_key<C, T, A>::char_type const* subKeyName)
  1331. {
  1332. hkey_type hkey;
  1333. result_type res = traits_type::reg_open_key(m_hkey, subKeyName, &hkey, KEY_READ);
  1334. switch(res)
  1335. {
  1336. case ERROR_SUCCESS:
  1337. ::RegCloseKey(hkey);
  1338. case ERROR_ACCESS_DENIED:
  1339. return true;
  1340. default:
  1341. return false;
  1342. }
  1343. }
  1344. template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
  1345. inline ss_typename_type_ret_k basic_reg_key<C, T, A>::bool_type basic_reg_key<C, T, A>::has_value_(ss_typename_type_k basic_reg_key<C, T, A>::char_type const* valueName)
  1346. {
  1347. ws_dword_t valueType;
  1348. ss_byte_t data[1];
  1349. size_type cbData = sizeof(data);
  1350. result_type res = traits_type::reg_query_value(m_hkey, valueName, valueType, &data[0], cbData);
  1351. switch(res)
  1352. {
  1353. case ERROR_SUCCESS:
  1354. case ERROR_MORE_DATA:
  1355. return true;
  1356. default:
  1357. return false;
  1358. }
  1359. }
  1360. template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
  1361. inline basic_reg_value<C, T, A> basic_reg_key<C, T, A>::get_value(ss_typename_type_k basic_reg_key<C, T, A>::char_type const* valueName) const
  1362. {
  1363. return basic_reg_value<C, T, A>(m_hkey, valueName);
  1364. }
  1365. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  1366. /* ////////////////////////////////////////////////////////////////////// */
  1367. #ifndef _WINSTL_NO_NAMESPACE
  1368. # if defined(_STLSOFT_NO_NAMESPACE) || \
  1369. defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
  1370. } // namespace winstl
  1371. # else
  1372. } // namespace winstl_project
  1373. } // namespace stlsoft
  1374. # endif /* _STLSOFT_NO_NAMESPACE */
  1375. #endif /* !_WINSTL_NO_NAMESPACE */
  1376. #if defined(STLSOFT_CF_std_NAMESPACE)
  1377. namespace std
  1378. {
  1379. #if !defined(STLSOFT_COMPILER_IS_BORLAND)
  1380. inline void swap(winstl_ns_qual(reg_key_a)& lhs, winstl_ns_qual(reg_key_a)& rhs)
  1381. {
  1382. lhs.swap(rhs);
  1383. }
  1384. inline void swap(winstl_ns_qual(reg_key_w)& lhs, winstl_ns_qual(reg_key_w)& rhs)
  1385. {
  1386. lhs.swap(rhs);
  1387. }
  1388. #endif /* compiler */
  1389. } // anonymous namespace
  1390. #endif /* STLSOFT_CF_std_NAMESPACE */
  1391. /* ////////////////////////////////////////////////////////////////////// */
  1392. #endif /* WINSTL_INCL_WINSTL_REGISTRY_HPP_REG_KEY */
  1393. /* ///////////////////////////// end of file //////////////////////////// */