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.

383 lines
8.9 KiB

  1. /*++
  2. Copyright (C) 1999-2001 Microsoft Corporation
  3. Module Name:
  4. NTREG.CPP
  5. Abstract:
  6. History:
  7. --*/
  8. #include "precomp.h"
  9. #include <stdio.h>
  10. #include <oaidl.h>
  11. #include "ntreg.h"
  12. #include "adaputil.h"
  13. CNTRegistry::CNTRegistry() : m_hPrimaryKey(0),
  14. m_hSubkey(0),
  15. m_nStatus(0),
  16. m_nLastError(no_error)
  17. {
  18. }
  19. CNTRegistry::~CNTRegistry()
  20. {
  21. if (m_hSubkey)
  22. RegCloseKey(m_hSubkey);
  23. if (m_hPrimaryKey != m_hSubkey)
  24. RegCloseKey(m_hPrimaryKey);
  25. }
  26. int CNTRegistry::Open(HKEY hStart, WCHAR *pszStartKey)
  27. {
  28. int nStatus = no_error;
  29. m_nLastError = RegOpenKeyExW(hStart, pszStartKey,
  30. 0, KEY_ALL_ACCESS, &m_hPrimaryKey );
  31. switch( m_nLastError )
  32. {
  33. case ERROR_SUCCESS:
  34. nStatus = no_error; break;
  35. case ERROR_ACCESS_DENIED:
  36. nStatus = access_denied; break;
  37. case ERROR_FILE_NOT_FOUND:
  38. nStatus = not_found; break;
  39. default:
  40. nStatus = failed; break;
  41. }
  42. m_hSubkey = m_hPrimaryKey;
  43. return nStatus;
  44. }
  45. int CNTRegistry::MoveToSubkey(WCHAR *pszNewSubkey)
  46. {
  47. int nStatus = no_error;
  48. m_nLastError = RegOpenKeyExW(m_hPrimaryKey, pszNewSubkey, 0, KEY_ALL_ACCESS, &m_hSubkey );
  49. switch( m_nLastError )
  50. {
  51. case ERROR_SUCCESS:
  52. nStatus = no_error; break;
  53. case ERROR_ACCESS_DENIED:
  54. nStatus = access_denied; break;
  55. default:
  56. nStatus = failed; break;
  57. }
  58. return nStatus;
  59. }
  60. int CNTRegistry::DeleteValue(WCHAR *pwszValueName)
  61. {
  62. int nStatus = no_error;
  63. m_nLastError = RegDeleteValueW(m_hSubkey, pwszValueName);
  64. switch( m_nLastError )
  65. {
  66. case ERROR_SUCCESS:
  67. nStatus = no_error; break;
  68. case ERROR_ACCESS_DENIED:
  69. nStatus = access_denied; break;
  70. case ERROR_FILE_NOT_FOUND:
  71. nStatus = not_found; break;
  72. default:
  73. nStatus = failed; break;
  74. }
  75. return nStatus;
  76. }
  77. int CNTRegistry::GetDWORD(WCHAR *pwszValueName, DWORD *pdwValue)
  78. {
  79. int nStatus = no_error;
  80. DWORD dwSize = sizeof(DWORD);
  81. DWORD dwType = 0;
  82. m_nLastError = RegQueryValueExW(m_hSubkey, pwszValueName, 0, &dwType,
  83. LPBYTE(pdwValue), &dwSize);
  84. switch( m_nLastError )
  85. {
  86. case ERROR_SUCCESS:
  87. {
  88. if (dwType != REG_DWORD)
  89. nStatus = failed;
  90. else
  91. nStatus = no_error;
  92. }break;
  93. case ERROR_ACCESS_DENIED:
  94. nStatus = access_denied; break;
  95. case ERROR_FILE_NOT_FOUND:
  96. nStatus = not_found; break;
  97. default:
  98. nStatus = failed; break;
  99. }
  100. return nStatus;
  101. }
  102. int CNTRegistry::GetStr(WCHAR *pwszValueName, WCHAR **pwszValue)
  103. {
  104. *pwszValue = 0;
  105. DWORD dwSize = 0;
  106. DWORD dwType = 0;
  107. m_nLastError = RegQueryValueExW(m_hSubkey, pwszValueName, 0, &dwType,
  108. 0, &dwSize);
  109. if (m_nLastError != 0)
  110. {
  111. DEBUGTRACE( ( LOG_WMIADAP, "CNTRegistry::GetStr() failed: %X.\n", m_nLastError ) );
  112. return failed;
  113. }
  114. if ( ( dwType != REG_SZ ) && ( dwType != REG_EXPAND_SZ ) )
  115. {
  116. DEBUGTRACE( ( LOG_WMIADAP, "CNTRegistry::GetStr() failed due to an invalid registry data type.\n" ) );
  117. return failed;
  118. }
  119. WCHAR *p = new WCHAR[dwSize];
  120. m_nLastError = RegQueryValueExW(m_hSubkey, pwszValueName, 0, &dwType,
  121. LPBYTE(p), &dwSize);
  122. if (m_nLastError != 0)
  123. {
  124. delete [] p;
  125. DEBUGTRACE( ( LOG_WMIADAP, "CNTRegistry::GetStr() failed: %X.\n", m_nLastError ) );
  126. return failed;
  127. }
  128. if(dwType == REG_EXPAND_SZ)
  129. {
  130. WCHAR* wszTemp = NULL;
  131. // Get the initial length
  132. DWORD nSize = ExpandEnvironmentStringsW( (WCHAR *)p, wszTemp, 0 ) + 10;
  133. wszTemp = new WCHAR[ nSize ];
  134. ExpandEnvironmentStringsW( (WCHAR *)p, wszTemp, nSize - 1 );
  135. delete [] p;
  136. *pwszValue = wszTemp;
  137. }
  138. else
  139. *pwszValue = p;
  140. return no_error;
  141. }
  142. int CNTRegistry::GetBinary(WCHAR *pwszValueName, BYTE **ppBuffer)
  143. {
  144. int nStatus = no_error;
  145. DWORD dwSize = 0;
  146. DWORD dwType = 0;
  147. m_nLastError = RegQueryValueExW(m_hSubkey, pwszValueName, 0, &dwType, 0, &dwSize );
  148. switch( m_nLastError )
  149. {
  150. case ERROR_SUCCESS:
  151. nStatus = no_error; break;
  152. case ERROR_ACCESS_DENIED:
  153. nStatus = access_denied; break;
  154. case ERROR_FILE_NOT_FOUND:
  155. nStatus = not_found; break;
  156. default:
  157. nStatus = failed; break;
  158. }
  159. if ( no_error == nStatus )
  160. {
  161. if ( dwType != REG_BINARY )
  162. {
  163. nStatus = failed;
  164. }
  165. if ( no_error == nStatus )
  166. {
  167. BYTE* pBuffer = new BYTE[dwSize];
  168. m_nLastError = RegQueryValueExW(m_hSubkey, pwszValueName, 0, &dwType, pBuffer, &dwSize );
  169. if ( ERROR_SUCCESS != m_nLastError )
  170. {
  171. delete [] pBuffer;
  172. nStatus = failed;
  173. }
  174. else
  175. {
  176. *ppBuffer = pBuffer;
  177. }
  178. }
  179. }
  180. return nStatus;
  181. }
  182. int CNTRegistry::Enum( DWORD dwIndex, WCHAR **pwszValue, DWORD& dwSize )
  183. {
  184. if (pwszValue == NULL)
  185. {
  186. return failed;
  187. }
  188. DWORD dwBuffSize = dwSize;
  189. m_nLastError = RegEnumKeyExW(m_hSubkey, dwIndex, *pwszValue, &dwBuffSize,
  190. NULL, NULL, NULL, NULL );
  191. while ( m_nLastError == ERROR_MORE_DATA )
  192. {
  193. // Grow in 256 byte chunks
  194. dwBuffSize += 256;
  195. try
  196. {
  197. // Reallocate the buffer and retry
  198. WCHAR* p = new WCHAR[dwBuffSize];
  199. if ( NULL != *pwszValue )
  200. {
  201. delete *pwszValue;
  202. }
  203. *pwszValue = p;
  204. dwSize = dwBuffSize;
  205. m_nLastError = RegEnumKeyExW(m_hSubkey, dwIndex, *pwszValue, &dwBuffSize,
  206. NULL, NULL, NULL, NULL );
  207. }
  208. catch (...)
  209. {
  210. ERRORTRACE( ( LOG_WMIADAP, "CNTRegistry::Enum() failed due to out of memory exception.\n" ) );
  211. return out_of_memory;
  212. }
  213. }
  214. if ( ERROR_SUCCESS != m_nLastError )
  215. {
  216. if ( ERROR_NO_MORE_ITEMS == m_nLastError )
  217. {
  218. return no_more_items;
  219. }
  220. else
  221. {
  222. return failed;
  223. }
  224. }
  225. return no_error;
  226. }
  227. int CNTRegistry::GetMultiStr(WCHAR *pwszValueName, WCHAR** pwszValue, DWORD &dwSize)
  228. {
  229. //Find out the size of the buffer required
  230. DWORD dwType;
  231. m_nLastError = RegQueryValueExW(m_hSubkey, pwszValueName, 0, &dwType, NULL, &dwSize);
  232. //If the error is an unexpected one bail out
  233. if ((m_nLastError != ERROR_SUCCESS) || (dwType != REG_MULTI_SZ))
  234. {
  235. dwSize = 0;
  236. DEBUGTRACE( ( LOG_WMIADAP, "CNTRegistry::GetMultiStr() failed: %X.\n", m_nLastError ) );
  237. return failed;
  238. }
  239. if (dwSize == 0)
  240. {
  241. dwSize = 0;
  242. DEBUGTRACE( ( LOG_WMIADAP, "CNTRegistry::GetMultiStr() failed due to null string.\n" ) );
  243. return failed;
  244. }
  245. //allocate the buffer required
  246. WCHAR *pData = new WCHAR[dwSize];
  247. //get the values
  248. m_nLastError = RegQueryValueExW(m_hSubkey,
  249. pwszValueName,
  250. 0,
  251. &dwType,
  252. LPBYTE(pData),
  253. &dwSize);
  254. //if an error bail out
  255. if (m_nLastError != 0)
  256. {
  257. delete [] pData;
  258. dwSize = 0;
  259. DEBUGTRACE( ( LOG_WMIADAP, "CNTRegistry::GetMultiStr() failed: %X.\n", m_nLastError ) );
  260. return failed;
  261. }
  262. *pwszValue = pData;
  263. return no_error;
  264. }
  265. int CNTRegistry::SetDWORD(WCHAR *pwszValueName, DWORD dwValue)
  266. {
  267. int nStatus = no_error;
  268. m_nLastError = RegSetValueExW( m_hSubkey,
  269. pwszValueName,
  270. 0,
  271. REG_DWORD,
  272. (BYTE*)&dwValue,
  273. sizeof( dwValue ) );
  274. if ( m_nLastError != ERROR_SUCCESS )
  275. {
  276. nStatus = failed;
  277. }
  278. return nStatus;
  279. }
  280. int CNTRegistry::SetStr(WCHAR *pwszValueName, WCHAR *wszValue)
  281. {
  282. int nStatus = no_error;
  283. m_nLastError = RegSetValueExW( m_hSubkey,
  284. pwszValueName,
  285. 0,
  286. REG_SZ,
  287. (BYTE*)wszValue,
  288. sizeof(WCHAR) * (wcslen(wszValue) + 1) );
  289. if ( m_nLastError != ERROR_SUCCESS )
  290. {
  291. nStatus = failed;
  292. }
  293. return nStatus;
  294. }
  295. int CNTRegistry::SetBinary(WCHAR *pwszValueName, BYTE* pBuffer, DWORD dwSize )
  296. {
  297. int nStatus = no_error;
  298. m_nLastError = RegSetValueExW( m_hSubkey, pwszValueName, 0, REG_BINARY, pBuffer, dwSize );
  299. if ( ERROR_SUCCESS != m_nLastError )
  300. {
  301. nStatus = failed;
  302. }
  303. return nStatus;
  304. }