Source code of Windows XP (NT5)
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.

248 lines
6.4 KiB

  1. // Copyright (c) 1997-1999 Microsoft Corporation
  2. //
  3. // System Registry Class
  4. //
  5. // 7-9-98 sburns
  6. #ifndef REGISTRY_HPP_INCLUDED
  7. #define REGISTRY_HPP_INCLUDED
  8. class RegistryKey
  9. {
  10. public:
  11. RegistryKey();
  12. ~RegistryKey();
  13. HRESULT
  14. Close();
  15. HRESULT
  16. Create(
  17. HKEY parentKey,
  18. const String& subkeyName,
  19. DWORD options = REG_OPTION_NON_VOLATILE,
  20. REGSAM desiredAccess = KEY_WRITE,
  21. SECURITY_ATTRIBUTES* securityAttrs = 0,
  22. DWORD* disposition = 0);
  23. HRESULT
  24. Open(
  25. HKEY parentKey,
  26. const String& subkeyName,
  27. REGSAM desiredAccess = KEY_READ);
  28. // Returns Win32ToHresult(ERROR_INVALID_FUNCTION) if the type of the value
  29. // is not REG_DWORD, REG_DWORD_LITTLE_ENDIAN, or REG_DWORD_BIG_ENDIAN.
  30. HRESULT
  31. GetValue(
  32. const String& valueName,
  33. DWORD& value);
  34. // Retrieves the contents of the named value, and whether the type of the
  35. // key is REG_SZ or REG_EXPAND_SZ. Returns
  36. // Win32ToHresult(ERROR_INVALID_FUNCTION) if the type of the value is not
  37. // REG_SZ or REG_EXPAND_SZ
  38. //
  39. // valueName - name of the value.
  40. //
  41. // value - receives the contents of the value, if the read was successful.
  42. // cleared on failure.
  43. //
  44. // isExpandSz - set to true if the value is of type REG_EXPAND_SZ, false
  45. // if the type is REG_SZ (or an error ocurred).
  46. HRESULT
  47. GetValue(
  48. const String& valueName,
  49. String& value,
  50. bool& isExpandSz);
  51. // Calls GetValue(), and throws away the isExpandSz result.
  52. HRESULT
  53. GetValue(
  54. const String& valueName,
  55. String& value);
  56. // Inserts strings from a REG_MULTI_SZ value into any container from
  57. // which a std::BackInsertionSequence can be constructed, the elements
  58. // of which must be constructable from an PWSTR.
  59. //
  60. // BackInsertionSequence - any type that supports the construction of
  61. // a back_insert_iterator on itself, and has a value type that can be
  62. // constructed from an PWSTR.
  63. //
  64. // valueName - name of REG_MULTI_SZ value to retrieve.
  65. //
  66. // bii - a reference to a back_insert_iterator of the
  67. // BackInsertionSequence template parameter. The simplest way to make
  68. // one of these is to use the back_inserter helper function.
  69. //
  70. // Example:
  71. //
  72. // StringList container;
  73. // hr = key.GetValue(L"myValue", back_inserter(container));
  74. //
  75. // StringVector container;
  76. // hr = key.GetValue(L"myValue", back_inserter(container));
  77. template <class BackInsertableContainer>
  78. HRESULT
  79. GetValue(
  80. const String& valueName,
  81. std::back_insert_iterator<BackInsertableContainer>& bii)
  82. {
  83. LOG_FUNCTION2(RegistryKey::GetValue-MultiString, valueName);
  84. ASSERT(!valueName.empty());
  85. ASSERT(key);
  86. DWORD type = 0;
  87. DWORD size = 0;
  88. HRESULT hr = Win::RegQueryValueEx(key, valueName, &type, 0, &size);
  89. if (SUCCEEDED(hr))
  90. {
  91. if (type == REG_MULTI_SZ)
  92. {
  93. // now that we know the size, read the contents
  94. BYTE* buf = new BYTE[size]; // a bitesized buffer! Ha Ha!
  95. memset(buf, 0, size);
  96. type = 0;
  97. hr = Win::RegQueryValueEx(key, valueName, &type, buf, &size);
  98. if (SUCCEEDED(hr))
  99. {
  100. // pull off each of the null-terminated strings
  101. // the container values can be any type that can be constructed
  102. // from PWSTR...
  103. wchar_t* newbuf = reinterpret_cast<PWSTR>(buf);
  104. while (*newbuf)
  105. {
  106. size_t len = wcslen(newbuf);
  107. //lint --e(*) lint does not grok back_insert_iterator
  108. *bii++ = String(newbuf, len);
  109. // move to the next string, + 1 to skip the terminating null
  110. newbuf += len + 1;
  111. };
  112. delete[] buf;
  113. }
  114. }
  115. else
  116. {
  117. // caller requested a string from a non-multi-string key
  118. hr = Win32ToHresult(ERROR_INVALID_FUNCTION);
  119. }
  120. }
  121. return hr;
  122. }
  123. // Calls GetValue and returns the result, or an empty string on failure.
  124. String
  125. GetString(const String& valueName);
  126. // Creates and/or sets a value under the currently open key. Returns
  127. // S_OK on success.
  128. //
  129. // valueName - name of the value. If the value is not already present, it
  130. // is created with a REG_DWORD type.
  131. //
  132. // value - the value to br written.
  133. HRESULT
  134. SetValue(
  135. const String& valueName,
  136. DWORD value);
  137. // Creates and/or sets a value under the currently open key. Returns
  138. // S_OK on success.
  139. //
  140. // valueName - name of the value. If the value is not already present, it
  141. // is created.
  142. //
  143. // value - the value to br written.
  144. //
  145. // expand - if true, the value type is REG_EXPAND_SZ, if false, the value
  146. // type is REG_SZ.
  147. HRESULT
  148. SetValue(
  149. const String& valueName,
  150. const String& value,
  151. bool expand = false);
  152. template<class ForwardIterator>
  153. HRESULT
  154. SetValue(
  155. const String& valueName,
  156. ForwardIterator first,
  157. ForwardIterator last)
  158. {
  159. LOG_FUNCTION2(RegistryKey::SetValue--MultiString, valueName);
  160. ASSERT(!valueName.empty());
  161. // determine the size of the buffer to write
  162. size_t bufsize = 0;
  163. for (
  164. ForwardIterator f = first, l = last;
  165. f != l;
  166. ++f)
  167. {
  168. // + 1 for null terminator
  169. bufsize += (f->length() + 1) * sizeof(wchar_t);
  170. }
  171. // + 2 bytes for double-null terminator at very end
  172. bufsize += 2;
  173. BYTE* buf = new BYTE[bufsize];
  174. memset(buf, 0, bufsize);
  175. // copy the elements of the container into the buffer
  176. wchar_t* newbuf = reinterpret_cast<wchar_t*>(buf);
  177. wchar_t* copyPos = newbuf;
  178. for (
  179. f = first, l = last;
  180. f != l;
  181. ++f)
  182. {
  183. copyPos = std::copy(f->begin(), f->end(), copyPos);
  184. // skip a character for terminating null
  185. copyPos++;
  186. }
  187. // write the buffer to the registry
  188. HRESULT hr =
  189. Win::RegSetValueEx(
  190. key,
  191. valueName,
  192. REG_MULTI_SZ,
  193. buf,
  194. bufsize);
  195. delete[] buf;
  196. return hr;
  197. }
  198. private:
  199. HKEY key;
  200. };
  201. #endif // REGISTRY_HPP_INCLUDED