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.

340 lines
6.4 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows NT **/
  3. /** Copyright(c) Microsoft Corp., 1997 **/
  4. /**********************************************************************/
  5. /*
  6. registry.cxx
  7. This module contains registry classes.
  8. FILE HISTORY:
  9. 7/7/97 michth ported from metadata.
  10. */
  11. extern "C" {
  12. #include <nt.h>
  13. #include <ntrtl.h>
  14. #include <nturtl.h>
  15. }
  16. #include <dbgutil.h>
  17. #include <apiutil.h>
  18. #include <loadmd.hxx>
  19. #include <loadadm.hxx>
  20. #include <ole2.h>
  21. #include <inetsvcs.h>
  22. #include <buffer.hxx>
  23. #include <registry.hxx>
  24. MDRegKey::MDRegKey (
  25. HKEY hKeyBase,
  26. LPCTSTR pchSubKey,
  27. REGSAM regSam,
  28. LPCTSTR pchServerName
  29. )
  30. : m_hKey(NULL),
  31. m_dwDisposition(0)
  32. {
  33. HKEY hkBase = NULL ;
  34. DWORD err = ERROR_SUCCESS;
  35. if ( pchServerName != NULL)
  36. {
  37. //
  38. // This is a remote connection.
  39. //
  40. err = ::RegConnectRegistry((LPTSTR)pchServerName, hKeyBase, &hkBase);
  41. if (err != ERROR_SUCCESS)
  42. {
  43. hkBase = NULL ;
  44. SetLastError(err);
  45. }
  46. }
  47. else
  48. {
  49. hkBase = hKeyBase ;
  50. }
  51. if (err == ERROR_SUCCESS)
  52. {
  53. if ( pchSubKey )
  54. {
  55. err = ::RegOpenKeyEx( hkBase, pchSubKey, 0, regSam, & m_hKey ) ;
  56. }
  57. else
  58. {
  59. m_hKey = hkBase ;
  60. hkBase = NULL ;
  61. }
  62. if ( hkBase && hkBase != hKeyBase )
  63. {
  64. ::RegCloseKey( hkBase ) ;
  65. }
  66. }
  67. if ( err != ERROR_SUCCESS)
  68. {
  69. m_hKey = NULL ;
  70. }
  71. SetLastError(err);
  72. }
  73. //
  74. // Constructor creating a new key.
  75. //
  76. MDRegKey::MDRegKey (
  77. LPCTSTR pchSubKey,
  78. HKEY hKeyBase,
  79. DWORD dwOptions,
  80. REGSAM regSam,
  81. LPSECURITY_ATTRIBUTES pSecAttr,
  82. LPCTSTR pchServerName
  83. )
  84. : m_hKey(NULL),
  85. m_dwDisposition(0)
  86. {
  87. HKEY hkBase = NULL ;
  88. DWORD err = 0;
  89. if (pchServerName != NULL)
  90. {
  91. //
  92. // This is a remote connection.
  93. //
  94. err = ::RegConnectRegistry((LPTSTR)pchServerName, hKeyBase, & hkBase);
  95. if (err != ERROR_SUCCESS)
  96. {
  97. hkBase = NULL;
  98. SetLastError(err);
  99. }
  100. }
  101. else
  102. {
  103. hkBase = hKeyBase ;
  104. }
  105. if (err == ERROR_SUCCESS)
  106. {
  107. LPCTSTR szEmpty = TEXT("") ;
  108. err = ::RegCreateKeyEx( hkBase, pchSubKey, 0, (TCHAR *) szEmpty,
  109. dwOptions, regSam, pSecAttr, &m_hKey, &m_dwDisposition );
  110. }
  111. if (err != ERROR_SUCCESS)
  112. {
  113. m_hKey = NULL ;
  114. }
  115. SetLastError(err);
  116. }
  117. MDRegKey::~MDRegKey()
  118. {
  119. if (m_hKey != NULL)
  120. {
  121. ::RegCloseKey( m_hKey ) ;
  122. }
  123. }
  124. DWORD
  125. MDRegKey::QueryValue (
  126. LPTSTR pchValueName,
  127. DWORD * pdwType,
  128. DWORD * pdwSize,
  129. BUFFER *pbufData
  130. )
  131. {
  132. DWORD dwReturn = ERROR_SUCCESS;
  133. *pdwSize = pbufData->QuerySize();
  134. dwReturn = ::RegQueryValueEx(*this, (LPTSTR) pchValueName,
  135. 0, pdwType, (PBYTE) pbufData->QueryPtr(), pdwSize);
  136. if (dwReturn == ERROR_MORE_DATA) {
  137. if (pbufData->Resize(*pdwSize)) {
  138. *pdwSize = pbufData->QuerySize();
  139. dwReturn = ::RegQueryValueEx(*this, (LPTSTR) pchValueName,
  140. 0, pdwType, (PBYTE)pbufData->QueryPtr(), pdwSize);
  141. }
  142. }
  143. return dwReturn;
  144. }
  145. //
  146. // Overloaded value setting members.
  147. //
  148. DWORD
  149. MDRegKey::SetValue (
  150. LPCTSTR pchValueName,
  151. DWORD dwType,
  152. DWORD dwSize,
  153. PBYTE pbData
  154. )
  155. {
  156. return ::RegSetValueEx( *this, pchValueName, 0, dwType,
  157. pbData, dwSize );
  158. }
  159. DWORD
  160. MDRegKey::DeleteValue (
  161. LPCTSTR pchValueName
  162. )
  163. {
  164. return ::RegDeleteValue( *this, (LPTSTR) pchValueName);
  165. }
  166. DWORD
  167. MDRegKey::QueryKeyInfo (
  168. MDREGKEY_KEY_INFO * pRegKeyInfo
  169. )
  170. {
  171. DWORD err = 0 ;
  172. pRegKeyInfo->dwClassNameSize = sizeof pRegKeyInfo->chBuff - 1 ;
  173. err = ::RegQueryInfoKey(*this,
  174. pRegKeyInfo->chBuff,
  175. &pRegKeyInfo->dwClassNameSize,
  176. NULL,
  177. &pRegKeyInfo->dwNumSubKeys,
  178. &pRegKeyInfo->dwMaxSubKey,
  179. &pRegKeyInfo->dwMaxClass,
  180. &pRegKeyInfo->dwMaxValues,
  181. &pRegKeyInfo->dwMaxValueName,
  182. &pRegKeyInfo->dwMaxValueData,
  183. &pRegKeyInfo->dwSecDesc,
  184. &pRegKeyInfo->ftKey
  185. );
  186. return err ;
  187. }
  188. //
  189. // Iteration class
  190. //
  191. MDRegKeyIter::MDRegKeyIter (
  192. MDRegKey & regKey
  193. )
  194. : m_rk_iter( regKey ),
  195. m_p_buffer( NULL ),
  196. m_cb_buffer( 0 )
  197. {
  198. DWORD err = 0 ;
  199. MDRegKey::MDREGKEY_KEY_INFO regKeyInfo ;
  200. Reset() ;
  201. err = regKey.QueryKeyInfo( & regKeyInfo ) ;
  202. if ( err == 0 )
  203. {
  204. m_cb_buffer = regKeyInfo.dwMaxSubKey + sizeof (DWORD) ;
  205. m_p_buffer = new TCHAR [ m_cb_buffer ] ;
  206. if (m_p_buffer == NULL) {
  207. err = ERROR_NOT_ENOUGH_MEMORY ;
  208. }
  209. }
  210. SetLastError(err);
  211. }
  212. MDRegKeyIter :: ~ MDRegKeyIter ()
  213. {
  214. delete [] m_p_buffer ;
  215. }
  216. //
  217. // Get the name (and optional last write time) of the next key.
  218. //
  219. DWORD MDRegKeyIter::Next(
  220. LPTSTR *ppszName,
  221. FILETIME *pTime,
  222. DWORD dwIndex
  223. )
  224. {
  225. DWORD err = 0;
  226. FILETIME ftDummy ;
  227. DWORD dwNameSize = m_cb_buffer ;
  228. if (dwIndex != 0xffffffff) {
  229. m_dw_index = dwIndex;
  230. }
  231. err = ::RegEnumKeyEx( m_rk_iter, m_dw_index, m_p_buffer, & dwNameSize,
  232. NULL, NULL, NULL, & ftDummy ) ;
  233. if (err == ERROR_SUCCESS)
  234. {
  235. ++m_dw_index;
  236. if ( pTime )
  237. {
  238. *pTime = ftDummy ;
  239. }
  240. *ppszName = m_p_buffer;
  241. }
  242. return err;
  243. }
  244. MDRegValueIter::MDRegValueIter (
  245. MDRegKey &regKey
  246. )
  247. : m_rk_iter(regKey),
  248. m_p_buffer(NULL),
  249. m_cb_buffer(0)
  250. {
  251. DWORD err = 0;
  252. MDRegKey::MDREGKEY_KEY_INFO regKeyInfo ;
  253. Reset() ;
  254. err = regKey.QueryKeyInfo( & regKeyInfo ) ;
  255. if (err == ERROR_SUCCESS)
  256. {
  257. m_cb_buffer = regKeyInfo.dwMaxValueName + sizeof (DWORD);
  258. m_p_buffer = new TCHAR [ m_cb_buffer ] ;
  259. if (m_p_buffer == NULL) {
  260. err = ERROR_NOT_ENOUGH_MEMORY ;
  261. }
  262. }
  263. SetLastError(err);
  264. }
  265. MDRegValueIter::~MDRegValueIter()
  266. {
  267. delete [] m_p_buffer;
  268. }
  269. DWORD
  270. MDRegValueIter::Next (
  271. LPTSTR * ppszName,
  272. DWORD * pdwType
  273. )
  274. {
  275. DWORD err = 0 ;
  276. DWORD dwNameLength = m_cb_buffer ;
  277. err = ::RegEnumValue(m_rk_iter, m_dw_index, m_p_buffer,
  278. &dwNameLength, NULL, pdwType, NULL, NULL );
  279. if ( err == ERROR_SUCCESS )
  280. {
  281. ++m_dw_index;
  282. *ppszName = m_p_buffer;
  283. }
  284. return err;
  285. }
  286.