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.

636 lines
26 KiB

  1. /* /////////////////////////////////////////////////////////////////////////
  2. * File: winstl/registry/reg_traits.hpp
  3. *
  4. * Purpose: Contains the reg_traits class template, and ANSI
  5. * and Unicode specialisations thereof.
  6. *
  7. * Created: 19th January 2002
  8. * Updated: 10th August 2009
  9. *
  10. * Thanks to: Sam Fisher for requesting reg_delete_tree().
  11. *
  12. * Home: http://stlsoft.org/
  13. *
  14. * Copyright (c) 2002-2009, Matthew Wilson and Synesis Software
  15. * All rights reserved.
  16. *
  17. * Redistribution and use in source and binary forms, with or without
  18. * modification, are permitted provided that the following conditions are met:
  19. *
  20. * - Redistributions of source code must retain the above copyright notice, this
  21. * list of conditions and the following disclaimer.
  22. * - Redistributions in binary form must reproduce the above copyright notice,
  23. * this list of conditions and the following disclaimer in the documentation
  24. * and/or other materials provided with the distribution.
  25. * - Neither the name(s) of Matthew Wilson and Synesis Software nor the names of
  26. * any contributors may be used to endorse or promote products derived from
  27. * this software without specific prior written permission.
  28. *
  29. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  30. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  31. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  32. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  33. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  34. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  35. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  36. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  37. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  38. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  39. * POSSIBILITY OF SUCH DAMAGE.
  40. *
  41. * ////////////////////////////////////////////////////////////////////// */
  42. /** \file winstl/registry/reg_traits.hpp
  43. *
  44. * \brief [C++ only] Definition of the winstl::reg_traits class template
  45. * (\ref group__library__windows_registry "Windows Registry" Library).
  46. */
  47. #ifndef WINSTL_INCL_WINSTL_REGISTRY_HPP_REG_TRAITS
  48. #define WINSTL_INCL_WINSTL_REGISTRY_HPP_REG_TRAITS
  49. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  50. # define WINSTL_VER_WINSTL_REGISTRY_HPP_REG_TRAITS_MAJOR 3
  51. # define WINSTL_VER_WINSTL_REGISTRY_HPP_REG_TRAITS_MINOR 5
  52. # define WINSTL_VER_WINSTL_REGISTRY_HPP_REG_TRAITS_REVISION 1
  53. # define WINSTL_VER_WINSTL_REGISTRY_HPP_REG_TRAITS_EDIT 77
  54. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  55. /* /////////////////////////////////////////////////////////////////////////
  56. * Includes
  57. */
  58. #ifndef WINSTL_INCL_WINSTL_H_WINSTL
  59. # include <winstl/winstl.h>
  60. #endif /* !WINSTL_INCL_WINSTL_H_WINSTL */
  61. #ifndef WINSTL_INCL_WINSTL_REGISTRY_UTIL_HPP_DEFS
  62. # include <winstl/registry/util/defs.hpp>
  63. #endif /* !WINSTL_INCL_WINSTL_REGISTRY_UTIL_HPP_DEFS */
  64. #ifndef WINSTL_INCL_WINSTL_SYSTEM_HPP_SYSTEM_TRAITS
  65. # include <winstl/system/system_traits.hpp>
  66. #endif /* !WINSTL_INCL_WINSTL_SYSTEM_HPP_SYSTEM_TRAITS */
  67. /* /////////////////////////////////////////////////////////////////////////
  68. * Namespace
  69. */
  70. #ifndef _WINSTL_NO_NAMESPACE
  71. # if defined(_STLSOFT_NO_NAMESPACE) || \
  72. defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
  73. /* There is no stlsoft namespace, so must define ::winstl */
  74. namespace winstl
  75. {
  76. # else
  77. /* Define stlsoft::winstl_project */
  78. namespace stlsoft
  79. {
  80. namespace winstl_project
  81. {
  82. # endif /* _STLSOFT_NO_NAMESPACE */
  83. #endif /* !_WINSTL_NO_NAMESPACE */
  84. /* ////////////////////////////////////////////////////////////////////// */
  85. #ifdef STLSOFT_DOCUMENTATION_SKIP_SECTION
  86. /** Traits for accessing the correct registry functions for a given character type
  87. *
  88. * \ingroup group__library__windows_registry
  89. *
  90. * reg_traits is a traits class for determining the correct registry
  91. * structures and functions for a given character type.
  92. *
  93. * \param C The character type
  94. */
  95. template <ss_typename_param_k C>
  96. struct reg_traits
  97. : public system_traits<C>
  98. {
  99. /// \name Member Types
  100. /// @{
  101. public:
  102. /// The character type
  103. typedef C char_type;
  104. /// The size type
  105. typedef ws_size_t size_type;
  106. /// The difference type
  107. typedef ws_ptrdiff_t difference_type;
  108. /// The registry key type
  109. typedef HKEY hkey_type;
  110. /// The string type
  111. typedef reg_string_t string_type; // Placeholder only
  112. /// The time type
  113. typedef FILETIME time_type;
  114. /// The API result type (LONG)
  115. typedef LONG result_type;
  116. /// @}
  117. /// \name Operations
  118. /// @{
  119. public:
  120. /// Duplicates a registry key
  121. ///
  122. /// \deprecated Use reg_dup_key() instead
  123. static hkey_type key_dup( hkey_type hkey
  124. , REGSAM samDesired = KEY_ALL_ACCESS
  125. , result_type* result = NULL);
  126. /// Duplicates a registry key
  127. static hkey_type reg_dup_key( hkey_type hkey
  128. , REGSAM samDesired = KEY_ALL_ACCESS
  129. , result_type* result = NULL);
  130. /// Opens a registry sub-key
  131. static result_type reg_open_key( hkey_type hkey,
  132. char_type const* sub_key_name,
  133. hkey_type* hkey_result,
  134. REGSAM samDesired = KEY_ALL_ACCESS);
  135. /// Opens a registry sub-key
  136. static result_type reg_create_key( hkey_type hkey,
  137. char_type const* sub_key_name,
  138. hkey_type* hkey_result,
  139. REGSAM samDesired = KEY_ALL_ACCESS);
  140. static result_type reg_create_key( hkey_type hkey,
  141. char_type const* sub_key_name,
  142. hkey_type* hkey_result,
  143. ws_bool_t& bCreated,
  144. REGSAM samDesired = KEY_ALL_ACCESS);
  145. /// Destroys a registry sub-key
  146. static result_type reg_delete_key( hkey_type hkey,
  147. char_type const* sub_key_name);
  148. /// Queries a registry key value
  149. static result_type reg_query_value(hkey_type hkey,
  150. char_type const* valueName,
  151. ws_dword_t& valueType,
  152. void* data,
  153. size_type &cbData);
  154. /// Sets the value of the named value.
  155. static result_type reg_set_value( hkey_type hkey
  156. , char_type const* valueName
  157. , ws_dword_t valueType
  158. , void const* data
  159. , size_type cbData);
  160. /// Deletes the named value.
  161. static result_type reg_delete_value(hkey_type hkey
  162. , char_type const* valueName);
  163. /// Deletes the key and all sub-keys, permissions allowing
  164. static result_type reg_delete_tree(
  165. hkey_type hkey
  166. , char_type const* sub_key_name
  167. );
  168. /// Queries a registry key's characteristics
  169. static result_type reg_query_info( hkey_type hkey,
  170. char_type* key_class,
  171. size_type* cch_key_class,
  172. ws_uint32_t* c_sub_keys,
  173. size_type* cch_sub_key_max,
  174. size_type* cch_key_class_max,
  175. ws_uint32_t* c_values,
  176. size_type* cch_valueName_max,
  177. size_type* cb_value_data_max,
  178. size_type* cb_security_descriptor_max,
  179. time_type* time_last_write);
  180. /// Enumerates a registry key's sub-keys
  181. static result_type reg_enum_key( hkey_type hkey,
  182. ws_dword_t index,
  183. char_type* key_name,
  184. size_type* cch_key_name,
  185. time_type* time_last_write = NULL);
  186. /// [DEPRECATED] Enumerates a registry key's sub-keys
  187. ///
  188. /// \deprecated This is deprecated in favour of reg_enum_key(hkey_type, ws_dword_t, char_type*, size_type*, time_type *)
  189. static result_type reg_enum_key( hkey_type hkey,
  190. ws_dword_t index,
  191. char_type* key_name,
  192. size_type* cch_key_name,
  193. char_type* key_class,
  194. size_type* cch_key_class,
  195. time_type* time_last_write);
  196. /// Enumerates a registry key's values
  197. static result_type reg_enum_value( hkey_type hkey,
  198. ws_dword_t index,
  199. char_type* valueName,
  200. size_type* cch_valueName,
  201. ws_dword_t* valueType,
  202. void* data,
  203. size_type &cbData);
  204. /// Enumerates a registry key's values
  205. static result_type reg_enum_value( hkey_type hkey,
  206. ws_dword_t index,
  207. char_type* valueName,
  208. size_type* cch_valueName);
  209. /// @}
  210. };
  211. #else /* ? STLSOFT_DOCUMENTATION_SKIP_SECTION */
  212. template <ss_typename_param_k C>
  213. struct reg_traits;
  214. STLSOFT_TEMPLATE_SPECIALISATION
  215. struct reg_traits<ws_char_a_t>
  216. : public system_traits<ws_char_a_t>
  217. {
  218. public:
  219. typedef ws_char_a_t char_type;
  220. typedef ws_size_t size_type;
  221. typedef ws_ptrdiff_t difference_type;
  222. typedef HKEY hkey_type;
  223. typedef reg_string_a_t string_type;
  224. typedef FILETIME time_type;
  225. typedef LONG result_type;
  226. public:
  227. static hkey_type key_dup(hkey_type hkey, REGSAM samDesired, result_type *result = NULL)
  228. {
  229. return reg_dup_key(hkey, samDesired, result);
  230. }
  231. static hkey_type reg_dup_key(hkey_type hkey, REGSAM samDesired, result_type *result = NULL)
  232. {
  233. hkey_type hkeyDup;
  234. result_type res = ::RegOpenKeyExA(hkey, "", 0, samDesired, &hkeyDup);
  235. if(ERROR_SUCCESS != res)
  236. {
  237. hkeyDup = NULL;
  238. }
  239. if(NULL != result)
  240. {
  241. *result = res;
  242. }
  243. return hkeyDup;
  244. }
  245. static result_type reg_open_key(hkey_type hkey, char_type const* sub_key_name, hkey_type *hkey_result, REGSAM samDesired = KEY_ALL_ACCESS)
  246. {
  247. return ::RegOpenKeyExA(hkey, sub_key_name, 0, samDesired, hkey_result);
  248. }
  249. static result_type reg_create_key(hkey_type hkey, char_type const* sub_key_name, hkey_type *hkey_result, REGSAM samDesired = KEY_ALL_ACCESS)
  250. {
  251. return ::RegCreateKeyExA(hkey, sub_key_name, 0, NULL, 0, samDesired, NULL, hkey_result, NULL);
  252. }
  253. static result_type reg_create_key(hkey_type hkey, char_type const* sub_key_name, hkey_type *hkey_result, ws_bool_t &bCreated, REGSAM samDesired = KEY_ALL_ACCESS)
  254. {
  255. DWORD disposition;
  256. result_type res = ::RegCreateKeyExA(hkey, sub_key_name, 0, NULL, 0, samDesired, NULL, hkey_result, &disposition);
  257. bCreated = (ERROR_SUCCESS == res) && (REG_CREATED_NEW_KEY == disposition);
  258. return res;
  259. }
  260. static result_type reg_delete_key(hkey_type hkey, char_type const* sub_key_name)
  261. {
  262. return ::RegDeleteKeyA(hkey, sub_key_name);
  263. }
  264. static result_type reg_query_value(hkey_type hkey, char_type const* valueName, ws_dword_t& valueType, void* data, size_type &cbData)
  265. {
  266. return ::RegQueryValueExA(hkey, valueName, NULL, &valueType, static_cast<LPBYTE>(data), reinterpret_cast<LPDWORD>(&cbData));
  267. }
  268. static result_type reg_set_value(hkey_type hkey, char_type const* valueName, ws_dword_t valueType, void const* data, size_type cbData)
  269. {
  270. return ::RegSetValueExA(hkey, valueName, 0, valueType, static_cast<BYTE const*>(data), static_cast<DWORD>(cbData));
  271. }
  272. static result_type reg_delete_value(hkey_type hkey, char_type const* valueName)
  273. {
  274. return ::RegDeleteValueA(hkey, valueName);
  275. }
  276. static result_type reg_delete_tree(
  277. hkey_type hkey
  278. , char_type const* sub_key_name
  279. )
  280. {
  281. result_type res = execute_dynamic_("advapi32.dll", "RegDeleteTreeA", hkey, sub_key_name);
  282. if(ERROR_PROC_NOT_FOUND == res)
  283. {
  284. res = execute_dynamic_("shlwapi.dll", "SHDeleteKeyA", hkey, sub_key_name);
  285. }
  286. return res;
  287. }
  288. static result_type reg_query_info( hkey_type hkey,
  289. char_type* key_class,
  290. size_type* cch_key_class,
  291. ws_uint32_t* c_sub_keys,
  292. size_type* cch_sub_key_max,
  293. size_type* cch_key_class_max,
  294. ws_uint32_t* c_values,
  295. size_type* cch_valueName_max,
  296. size_type* cb_value_data_max,
  297. size_type* cb_security_descriptor_max,
  298. time_type* time_last_write)
  299. {
  300. if( NULL == cch_key_class &&
  301. NULL != key_class)
  302. {
  303. return ERROR_INVALID_PARAMETER;
  304. }
  305. return ::RegQueryInfoKeyA(hkey, key_class, reinterpret_cast<LPDWORD>(cch_key_class), NULL, reinterpret_cast<LPDWORD>(c_sub_keys), reinterpret_cast<LPDWORD>(cch_sub_key_max), reinterpret_cast<LPDWORD>(cch_key_class_max), reinterpret_cast<LPDWORD>(c_values), reinterpret_cast<LPDWORD>(cch_valueName_max), reinterpret_cast<LPDWORD>(cb_value_data_max), reinterpret_cast<LPDWORD>(cb_security_descriptor_max), time_last_write);
  306. }
  307. static result_type reg_enum_key( hkey_type hkey,
  308. ws_dword_t index,
  309. char_type* key_name,
  310. size_type* cch_key_name,
  311. time_type* time_last_write = NULL)
  312. {
  313. return ::RegEnumKeyExA(hkey, index, key_name, reinterpret_cast<LPDWORD>(cch_key_name), NULL, NULL, NULL, time_last_write);
  314. }
  315. static result_type reg_enum_key( hkey_type hkey,
  316. ws_dword_t index,
  317. char_type* key_name,
  318. size_type* cch_key_name,
  319. char_type* key_class,
  320. size_type* cch_key_class,
  321. time_type* time_last_write)
  322. {
  323. return ::RegEnumKeyExA(hkey, index, key_name, reinterpret_cast<LPDWORD>(cch_key_name), NULL, key_class, reinterpret_cast<LPDWORD>(cch_key_class), time_last_write);
  324. }
  325. static result_type reg_enum_value( hkey_type hkey,
  326. ws_dword_t index,
  327. char_type* valueName,
  328. size_type* cch_valueName,
  329. ws_dword_t* valueType,
  330. void* data,
  331. size_type &cbData)
  332. {
  333. return ::RegEnumValueA(hkey, index, valueName, reinterpret_cast<LPDWORD>(cch_valueName), NULL, valueType, reinterpret_cast<LPBYTE>(data), reinterpret_cast<LPDWORD>(&cbData));
  334. }
  335. static result_type reg_enum_value( hkey_type hkey,
  336. ws_dword_t index,
  337. char_type* valueName,
  338. size_type* cch_valueName)
  339. {
  340. return ::RegEnumValueA(hkey, index, valueName, reinterpret_cast<LPDWORD>(cch_valueName), NULL, NULL, NULL, NULL);
  341. }
  342. private:
  343. static result_type execute_dynamic_(
  344. ws_char_a_t const* module
  345. , ws_char_a_t const* function
  346. , hkey_type a1
  347. , char_type const* a2
  348. )
  349. {
  350. result_type r = ERROR_SUCCESS;
  351. HINSTANCE hinst = ::LoadLibraryA(module);
  352. if(NULL == hinst)
  353. {
  354. r = static_cast<result_type>(::GetLastError());
  355. }
  356. else
  357. {
  358. union
  359. {
  360. FARPROC fp;
  361. DWORD (STLSOFT_STDCALL* pfn)(HKEY, LPCSTR);
  362. } u;
  363. u.fp = ::GetProcAddress(hinst, function);
  364. if(NULL == u.fp)
  365. {
  366. r = static_cast<result_type>(::GetLastError());
  367. }
  368. else
  369. {
  370. r = static_cast<result_type>((*u.pfn)(a1, a2));
  371. }
  372. ::FreeLibrary(hinst);
  373. }
  374. return r;
  375. }
  376. };
  377. STLSOFT_TEMPLATE_SPECIALISATION
  378. struct reg_traits<ws_char_w_t>
  379. : public system_traits<ws_char_w_t>
  380. {
  381. public:
  382. typedef ws_char_w_t char_type;
  383. typedef ws_size_t size_type;
  384. typedef ws_ptrdiff_t difference_type;
  385. typedef HKEY hkey_type;
  386. typedef reg_string_w_t string_type;
  387. typedef FILETIME time_type;
  388. typedef LONG result_type;
  389. public:
  390. static hkey_type key_dup(hkey_type hkey, REGSAM samDesired, result_type *result = NULL)
  391. {
  392. return reg_dup_key(hkey, samDesired, result);
  393. }
  394. static hkey_type reg_dup_key(hkey_type hkey, REGSAM samDesired, result_type *result = NULL)
  395. {
  396. hkey_type hkeyDup;
  397. result_type res = ::RegOpenKeyExW(hkey, L"", 0, samDesired, &hkeyDup);
  398. if(ERROR_SUCCESS != res)
  399. {
  400. hkeyDup = NULL;
  401. }
  402. if(NULL != result)
  403. {
  404. *result = res;
  405. }
  406. return hkeyDup;
  407. }
  408. static result_type reg_open_key(hkey_type hkey, char_type const* sub_key_name, hkey_type *hkey_result, REGSAM samDesired = KEY_ALL_ACCESS)
  409. {
  410. return ::RegOpenKeyExW(hkey, sub_key_name, 0, samDesired, hkey_result);
  411. }
  412. static result_type reg_create_key(hkey_type hkey, char_type const* sub_key_name, hkey_type *hkey_result, REGSAM samDesired = KEY_ALL_ACCESS)
  413. {
  414. return ::RegCreateKeyExW(hkey, sub_key_name, 0, NULL, 0, samDesired, NULL, hkey_result, NULL);
  415. }
  416. static result_type reg_create_key(hkey_type hkey, char_type const* sub_key_name, hkey_type *hkey_result, ws_bool_t &bCreated, REGSAM samDesired = KEY_ALL_ACCESS)
  417. {
  418. DWORD disposition;
  419. result_type res = ::RegCreateKeyExW(hkey, sub_key_name, 0, NULL, 0, samDesired, NULL, hkey_result, &disposition);
  420. bCreated = (ERROR_SUCCESS == res) && (REG_CREATED_NEW_KEY == disposition);
  421. return res;
  422. }
  423. static result_type reg_delete_key(hkey_type hkey, char_type const* sub_key_name)
  424. {
  425. return ::RegDeleteKeyW(hkey, sub_key_name);
  426. }
  427. static result_type reg_query_value(hkey_type hkey, char_type const* valueName, ws_dword_t& valueType, void* data, size_type &cbData)
  428. {
  429. return ::RegQueryValueExW(hkey, valueName, NULL, &valueType, static_cast<LPBYTE>(data), reinterpret_cast<LPDWORD>(&cbData));
  430. }
  431. static result_type reg_set_value(hkey_type hkey, char_type const* valueName, ws_dword_t valueType, void const* data, size_type cbData)
  432. {
  433. return ::RegSetValueExW(hkey, valueName, 0, valueType, static_cast<BYTE const*>(data), static_cast<DWORD>(cbData));
  434. }
  435. static result_type reg_delete_value(hkey_type hkey, char_type const* valueName)
  436. {
  437. return ::RegDeleteValueW(hkey, valueName);
  438. }
  439. static result_type reg_delete_tree(
  440. hkey_type hkey
  441. , char_type const* sub_key_name
  442. )
  443. {
  444. result_type res = execute_dynamic_("advapi32.dll", "RegDeleteTreeW", hkey, sub_key_name);
  445. if(ERROR_PROC_NOT_FOUND == res)
  446. {
  447. res = execute_dynamic_("shlwapi.dll", "SHDeleteKeyW", hkey, sub_key_name);
  448. }
  449. return res;
  450. }
  451. static result_type reg_query_info( hkey_type hkey,
  452. char_type* key_class,
  453. size_type* cch_key_class,
  454. ws_uint32_t* c_sub_keys,
  455. size_type* cch_sub_key_max,
  456. size_type* cch_key_class_max,
  457. ws_uint32_t* c_values,
  458. size_type* cch_valueName_max,
  459. size_type* cb_value_data_max,
  460. size_type* cb_security_descriptor_max,
  461. time_type* time_last_write)
  462. {
  463. if( NULL == cch_key_class &&
  464. NULL != key_class)
  465. {
  466. return ERROR_INVALID_PARAMETER;
  467. }
  468. return ::RegQueryInfoKeyW(hkey, key_class, reinterpret_cast<LPDWORD>(cch_key_class), NULL, reinterpret_cast<LPDWORD>(c_sub_keys), reinterpret_cast<LPDWORD>(cch_sub_key_max), reinterpret_cast<LPDWORD>(cch_key_class_max), reinterpret_cast<LPDWORD>(c_values), reinterpret_cast<LPDWORD>(cch_valueName_max), reinterpret_cast<LPDWORD>(cb_value_data_max), reinterpret_cast<LPDWORD>(cb_security_descriptor_max), time_last_write);
  469. }
  470. static result_type reg_enum_key( hkey_type hkey,
  471. ws_dword_t index,
  472. char_type* key_name,
  473. size_type* cch_key_name,
  474. time_type* time_last_write = NULL)
  475. {
  476. return ::RegEnumKeyExW(hkey, index, key_name, reinterpret_cast<LPDWORD>(cch_key_name), NULL, NULL, NULL, time_last_write);
  477. }
  478. static result_type reg_enum_key( hkey_type hkey,
  479. ws_dword_t index,
  480. char_type* key_name,
  481. size_type* cch_key_name,
  482. char_type* key_class,
  483. size_type* cch_key_class,
  484. time_type* time_last_write)
  485. {
  486. return ::RegEnumKeyExW(hkey, index, key_name, reinterpret_cast<LPDWORD>(cch_key_name), NULL, key_class, reinterpret_cast<LPDWORD>(cch_key_class), time_last_write);
  487. }
  488. static result_type reg_enum_value( hkey_type hkey,
  489. ws_dword_t index,
  490. char_type* valueName,
  491. size_type* cch_valueName,
  492. ws_dword_t* valueType,
  493. void* data,
  494. size_type &cbData)
  495. {
  496. return ::RegEnumValueW(hkey, index, valueName, reinterpret_cast<LPDWORD>(cch_valueName), NULL, valueType, reinterpret_cast<LPBYTE>(data), reinterpret_cast<LPDWORD>(&cbData));
  497. }
  498. static result_type reg_enum_value( hkey_type hkey,
  499. ws_dword_t index,
  500. char_type* valueName,
  501. size_type* cch_valueName)
  502. {
  503. return ::RegEnumValueW(hkey, index, valueName, reinterpret_cast<LPDWORD>(cch_valueName), NULL, NULL, NULL, NULL);
  504. }
  505. private:
  506. static result_type execute_dynamic_(
  507. ws_char_a_t const* module
  508. , ws_char_a_t const* function
  509. , hkey_type a1
  510. , char_type const* a2
  511. )
  512. {
  513. result_type r = ERROR_SUCCESS;
  514. HINSTANCE hinst = ::LoadLibraryA(module);
  515. if(NULL == hinst)
  516. {
  517. r = static_cast<result_type>(::GetLastError());
  518. }
  519. else
  520. {
  521. union
  522. {
  523. FARPROC fp;
  524. DWORD (STLSOFT_STDCALL* pfn)(HKEY, LPCWSTR);
  525. } u;
  526. u.fp = ::GetProcAddress(hinst, function);
  527. if(NULL == u.fp)
  528. {
  529. r = static_cast<result_type>(::GetLastError());
  530. }
  531. else
  532. {
  533. r = static_cast<result_type>((*u.pfn)(a1, a2));
  534. }
  535. ::FreeLibrary(hinst);
  536. }
  537. return r;
  538. }
  539. };
  540. #endif /* STLSOFT_DOCUMENTATION_SKIP_SECTION */
  541. /* ////////////////////////////////////////////////////////////////////// */
  542. #ifndef _WINSTL_NO_NAMESPACE
  543. # if defined(_STLSOFT_NO_NAMESPACE) || \
  544. defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
  545. } // namespace winstl
  546. # else
  547. } // namespace winstl_project
  548. } // namespace stlsoft
  549. # endif /* _STLSOFT_NO_NAMESPACE */
  550. #endif /* !_WINSTL_NO_NAMESPACE */
  551. /* ////////////////////////////////////////////////////////////////////// */
  552. #endif /* WINSTL_INCL_WINSTL_REGISTRY_HPP_REG_TRAITS */
  553. /* ///////////////////////////// end of file //////////////////////////// */