Leaked source code of windows server 2003
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.

271 lines
7.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. // REVIEWED-2002/02/22-sburns This QueryValue call is ok.
  89. HRESULT hr = Win::RegQueryValueEx(key, valueName, &type, 0, &size);
  90. if (SUCCEEDED(hr))
  91. {
  92. if (type == REG_MULTI_SZ)
  93. {
  94. // now that we know the size, read the contents
  95. // add space for two null characters
  96. BYTE* buf = new BYTE[size + (2 * sizeof WCHAR)];
  97. // REVIEWED-2002/04/03-sburns correct byte count passed.
  98. ::ZeroMemory(buf, size + (2 * sizeof WCHAR));
  99. type = 0;
  100. hr = Win::RegQueryValueEx(key, valueName, &type, buf, &size);
  101. if (SUCCEEDED(hr))
  102. {
  103. // pull off each of the null-terminated strings
  104. // the container values can be any type that can be constructed
  105. // from PWSTR...
  106. wchar_t* newbuf = reinterpret_cast<PWSTR>(buf);
  107. while (*newbuf)
  108. {
  109. // REVIEWED-2002/04/03-sburns this wcslen call is safe
  110. // because we arranged for the buffer to be null-terminated
  111. size_t len = wcslen(newbuf);
  112. //lint --e(*) lint does not grok back_insert_iterator
  113. *bii++ = String(newbuf, len);
  114. // move to the next string, + 1 to skip the terminating null
  115. newbuf += len + 1;
  116. };
  117. delete[] buf;
  118. }
  119. }
  120. else
  121. {
  122. // caller requested a string from a non-multi-string key
  123. hr = Win32ToHresult(ERROR_INVALID_FUNCTION);
  124. }
  125. }
  126. return hr;
  127. }
  128. // Calls GetValue and returns the result, or an empty string on failure.
  129. String
  130. GetString(const String& valueName);
  131. // Creates and/or sets a value under the currently open key. Returns
  132. // S_OK on success.
  133. //
  134. // valueName - name of the value. If the value is not already present, it
  135. // is created with a REG_DWORD type.
  136. //
  137. // value - the value to br written.
  138. HRESULT
  139. SetValue(
  140. const String& valueName,
  141. DWORD value);
  142. // Creates and/or sets a value under the currently open key. Returns
  143. // S_OK on success.
  144. //
  145. // valueName - name of the value. If the value is not already present, it
  146. // is created.
  147. //
  148. // value - the value to br written.
  149. //
  150. // expand - if true, the value type is REG_EXPAND_SZ, if false, the value
  151. // type is REG_SZ.
  152. HRESULT
  153. SetValue(
  154. const String& valueName,
  155. const String& value,
  156. bool expand = false);
  157. template<class ForwardIterator>
  158. HRESULT
  159. SetValue(
  160. const String& valueName,
  161. ForwardIterator first,
  162. ForwardIterator last)
  163. {
  164. LOG_FUNCTION2(RegistryKey::SetValue--MultiString, valueName);
  165. ASSERT(!valueName.empty());
  166. // determine the size of the buffer to write
  167. size_t bufSizeInBytes = 0;
  168. for (
  169. ForwardIterator f = first, l = last;
  170. f != l;
  171. ++f)
  172. {
  173. // + 1 for null terminator
  174. bufSizeInBytes += (f->length() + 1) * sizeof(wchar_t);
  175. }
  176. // + 2 bytes for double-null terminator at very end
  177. bufSizeInBytes += 2;
  178. BYTE* buf = new BYTE[bufSizeInBytes];
  179. // REVIEWED-2002/02/27-sburns correct byte count passed. I know
  180. // BYTE is size 1, but what if that changed due to some screw up?
  181. ::ZeroMemory(buf, bufSizeInBytes * sizeof BYTE);
  182. // copy the elements of the container into the buffer
  183. wchar_t* newbuf = reinterpret_cast<wchar_t*>(buf);
  184. wchar_t* copyPos = newbuf;
  185. for (
  186. f = first, l = last;
  187. f != l;
  188. ++f)
  189. {
  190. copyPos = std::copy(f->begin(), f->end(), copyPos);
  191. // skip a character for terminating null
  192. copyPos++;
  193. }
  194. // write the buffer to the registry
  195. // REVIEWED-2002/02/27-sburns correct byte count passed.
  196. HRESULT hr =
  197. Win::RegSetValueEx(
  198. key,
  199. valueName,
  200. REG_MULTI_SZ,
  201. buf,
  202. bufSizeInBytes);
  203. delete[] buf;
  204. return hr;
  205. }
  206. private:
  207. HKEY key;
  208. };
  209. #endif // REGISTRY_HPP_INCLUDED