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.

413 lines
10 KiB

  1. //////////////////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // RegistryKey.cpp
  4. //
  5. // Copyright (C) 1998, 1999 Microsoft Corporation. All rights reserved.
  6. //
  7. // Abstract :
  8. //
  9. // This is the implementation of the CRegistryKey class. This class was created in order to
  10. // support automatic destruction of C++ object when an exception is thrown.
  11. //
  12. // History :
  13. //
  14. // 05/06/1999 luish Created
  15. //
  16. //////////////////////////////////////////////////////////////////////////////////////////////
  17. #include <windows.h>
  18. #include <shlwapi.h>
  19. #include "RegistryKey.h"
  20. #include "ExceptionHandler.h"
  21. #include "AppManDebug.h"
  22. #include "Win32API.h"
  23. #ifdef DBG_MODULE
  24. #undef DBG_MODULE
  25. #endif
  26. #define DBG_MODULE DBG_REGISTRY
  27. //////////////////////////////////////////////////////////////////////////////////////////////
  28. //
  29. //////////////////////////////////////////////////////////////////////////////////////////////
  30. CRegistryKey::CRegistryKey(void)
  31. {
  32. FUNCTION("CRegistryKey::CRegistryKey (void)");
  33. m_fKeyOpen = FALSE;
  34. }
  35. //////////////////////////////////////////////////////////////////////////////////////////////
  36. //
  37. //////////////////////////////////////////////////////////////////////////////////////////////
  38. CRegistryKey::~CRegistryKey(void)
  39. {
  40. FUNCTION("CRegistryKey::~CRegistryKey (void)");
  41. CloseKey();
  42. }
  43. //////////////////////////////////////////////////////////////////////////////////////////////
  44. //
  45. //////////////////////////////////////////////////////////////////////////////////////////////
  46. STDMETHODIMP CRegistryKey::EnumKeys(const DWORD dwIndex, LPSTR lpszSubKeyName, LPDWORD lpdwSubKeyNameLen)
  47. {
  48. FUNCTION("CRegistryKey::EnumKeys ()");
  49. FILETIME sFileTime;
  50. //
  51. // If there is no currently opened registry key, then GetValue was called unexpectedly
  52. //
  53. if (!m_fKeyOpen)
  54. {
  55. THROW(E_UNEXPECTED);
  56. }
  57. if (ERROR_SUCCESS != RegEnumKeyEx(m_hRegistryKey, dwIndex, lpszSubKeyName, lpdwSubKeyNameLen, NULL, NULL, NULL, &sFileTime))
  58. {
  59. return S_FALSE;
  60. }
  61. return S_OK;
  62. }
  63. //////////////////////////////////////////////////////////////////////////////////////////////
  64. //
  65. //////////////////////////////////////////////////////////////////////////////////////////////
  66. STDMETHODIMP CRegistryKey::CheckForExistingKey(HKEY hKey, LPCSTR lpszSubKeyName)
  67. {
  68. FUNCTION("CRegistryKey::CheckForExistingKey ()");
  69. HKEY hRegistryKey;
  70. if (ERROR_SUCCESS != RegOpenKeyEx(hKey, lpszSubKeyName, 0, KEY_READ, &hRegistryKey))
  71. {
  72. return S_FALSE;
  73. }
  74. RegCloseKey(hRegistryKey);
  75. return S_OK;
  76. }
  77. //////////////////////////////////////////////////////////////////////////////////////////////
  78. //
  79. //////////////////////////////////////////////////////////////////////////////////////////////
  80. STDMETHODIMP CRegistryKey::CreateKey(HKEY hKey, LPCSTR lpszSubKeyName, const DWORD dwOptions, const REGSAM samDesired, BOOL bSpecifySecurityAttributes, LPDWORD lpdwDisposition)
  81. {
  82. FUNCTION("CRegistryKey::CreateKey ()");
  83. LONG lReturn = ERROR_SUCCESS;
  84. HRESULT hResult = S_OK;
  85. CWin32API oWin32API;
  86. //
  87. // Make sure that current registry is closed before proceeding
  88. //
  89. CloseKey();
  90. //
  91. // Create the new key
  92. //
  93. if ((!(OS_VERSION_9x & oWin32API.GetOSVersion()))&&(bSpecifySecurityAttributes))
  94. {
  95. SECURITY_ATTRIBUTES sSecurityAttributes = {0};
  96. SECURITY_DESCRIPTOR sSecurityDescriptor = {0};
  97. sSecurityAttributes.nLength = sizeof sSecurityAttributes;
  98. sSecurityAttributes.lpSecurityDescriptor = &sSecurityDescriptor;
  99. InitializeSecurityDescriptor(&sSecurityDescriptor, SECURITY_DESCRIPTOR_REVISION);
  100. SetSecurityDescriptorDacl(&sSecurityDescriptor, TRUE, NULL, FALSE);
  101. lReturn = RegCreateKeyEx(hKey, lpszSubKeyName, 0, NULL, dwOptions, samDesired, &sSecurityAttributes, &m_hRegistryKey, lpdwDisposition);
  102. }
  103. else
  104. {
  105. lReturn = RegCreateKeyEx(hKey, lpszSubKeyName, 0, NULL, dwOptions, samDesired, NULL, &m_hRegistryKey, lpdwDisposition);
  106. }
  107. if (lReturn != ERROR_SUCCESS)
  108. {
  109. if (lReturn == ERROR_ACCESS_DENIED)
  110. {
  111. hResult = E_ACCESSDENIED;
  112. }
  113. else
  114. {
  115. hResult = E_FAIL;
  116. }
  117. THROW(hResult);
  118. }
  119. m_fKeyOpen = TRUE;
  120. return S_OK;
  121. }
  122. //////////////////////////////////////////////////////////////////////////////////////////////
  123. //
  124. //////////////////////////////////////////////////////////////////////////////////////////////
  125. STDMETHODIMP CRegistryKey::OpenKey(HKEY hKey, LPCSTR lpszSubKeyName, const REGSAM samDesired)
  126. {
  127. FUNCTION("CRegistryKey::OpenKey ()");
  128. //
  129. // Make sure that current registry is closed before proceeding
  130. //
  131. CloseKey();
  132. //
  133. // Open the existing key
  134. //
  135. if (ERROR_SUCCESS != RegOpenKeyEx(hKey, lpszSubKeyName, 0, samDesired, &m_hRegistryKey))
  136. {
  137. THROW(E_FAIL);
  138. }
  139. m_fKeyOpen = TRUE;
  140. return S_OK;
  141. }
  142. //////////////////////////////////////////////////////////////////////////////////////////////
  143. //
  144. //////////////////////////////////////////////////////////////////////////////////////////////
  145. STDMETHODIMP CRegistryKey::CloseKey(void)
  146. {
  147. FUNCTION("CRegistryKey::CloseKey ()");
  148. if (m_fKeyOpen)
  149. {
  150. RegCloseKey(m_hRegistryKey);
  151. m_fKeyOpen = FALSE;
  152. }
  153. return S_OK;
  154. }
  155. //////////////////////////////////////////////////////////////////////////////////////////////
  156. //
  157. //////////////////////////////////////////////////////////////////////////////////////////////
  158. STDMETHODIMP CRegistryKey::DeleteKey(HKEY hKey, LPCSTR lpszSubKeyName)
  159. {
  160. FUNCTION("CRegistryKey::DeleteKey ()");
  161. HRESULT hResult = S_OK;
  162. DWORD dwSubKeyNameLen;
  163. HKEY hRegistryKey;
  164. FILETIME sFileTime;
  165. CHAR strSubKeyName[MAX_PATH];
  166. CHAR strFullSubKeyName[MAX_PATH];
  167. //
  168. // Recursively delete all subkeys
  169. //
  170. if (ERROR_SUCCESS == RegOpenKeyEx(hKey, lpszSubKeyName, 0, KEY_ALL_ACCESS, &hRegistryKey))
  171. {
  172. dwSubKeyNameLen = MAX_PATH;
  173. while ((S_OK == hResult)&&(ERROR_SUCCESS == RegEnumKeyEx(hRegistryKey, 0, strSubKeyName, &dwSubKeyNameLen, NULL, NULL, NULL, &sFileTime)))
  174. {
  175. sprintf(strFullSubKeyName, "%s\\%s", lpszSubKeyName, strSubKeyName);
  176. hResult = DeleteKey(hKey, strFullSubKeyName);
  177. dwSubKeyNameLen = MAX_PATH;
  178. }
  179. //
  180. // Close the key
  181. //
  182. RegCloseKey(hRegistryKey);
  183. //
  184. // If all the subkeys were successfully deleted
  185. //
  186. if (S_OK == hResult)
  187. {
  188. //
  189. // Delete this subkey
  190. //
  191. if (ERROR_SUCCESS != RegDeleteKey(hKey, lpszSubKeyName))
  192. {
  193. hResult = E_FAIL;
  194. }
  195. }
  196. }
  197. return hResult;
  198. }
  199. //////////////////////////////////////////////////////////////////////////////////////////////
  200. //
  201. //////////////////////////////////////////////////////////////////////////////////////////////
  202. STDMETHODIMP CRegistryKey::EnumValues(const DWORD dwIndex, LPSTR lpszValueName, LPDWORD lpdwValueNameLen, LPDWORD lpdwType, LPBYTE lpData, LPDWORD lpdwDataLen)
  203. {
  204. FUNCTION("CRegistryKey::EnumValues ()");
  205. //
  206. // If there is no currently opened registry key, then GetValue was called unexpectedly
  207. //
  208. if (!m_fKeyOpen)
  209. {
  210. THROW(E_UNEXPECTED);
  211. }
  212. if (ERROR_SUCCESS != RegEnumValue(m_hRegistryKey, dwIndex, lpszValueName, lpdwValueNameLen, NULL, lpdwType, lpData, lpdwDataLen))
  213. {
  214. return S_FALSE;
  215. }
  216. return S_OK;
  217. }
  218. //////////////////////////////////////////////////////////////////////////////////////////////
  219. //
  220. //////////////////////////////////////////////////////////////////////////////////////////////
  221. STDMETHODIMP CRegistryKey::CheckForExistingValue(LPCSTR lpszValueName)
  222. {
  223. FUNCTION("CRegistryKey::CheckForExistingValue ()");
  224. //
  225. // If there is no currently opened registry key, then CheckForExistingValue was
  226. // called unexpectedly
  227. //
  228. if (!m_fKeyOpen)
  229. {
  230. THROW(E_UNEXPECTED);
  231. }
  232. //
  233. // Check to see whether we can RegQueryValueEx() on the target. If we can then the value
  234. // exists, othersize it does not
  235. //
  236. if (ERROR_SUCCESS != RegQueryValueEx(m_hRegistryKey, lpszValueName, NULL, NULL, NULL, NULL))
  237. {
  238. return S_FALSE;
  239. }
  240. return S_OK;
  241. }
  242. //////////////////////////////////////////////////////////////////////////////////////////////
  243. //
  244. //////////////////////////////////////////////////////////////////////////////////////////////
  245. STDMETHODIMP CRegistryKey::GetValue(LPCSTR lpszValueName, LPDWORD lpdwType, LPBYTE lpData, LPDWORD lpdwDataLen)
  246. {
  247. FUNCTION("CRegistryKey::GetValue ()");
  248. //
  249. // If there is no currently opened registry key, then GetValue was called unexpectedly
  250. //
  251. if (!m_fKeyOpen)
  252. {
  253. THROW(E_UNEXPECTED);
  254. }
  255. if (ERROR_SUCCESS != RegQueryValueEx(m_hRegistryKey, lpszValueName, NULL, lpdwType, lpData, lpdwDataLen))
  256. {
  257. THROW(E_FAIL);
  258. }
  259. return S_OK;
  260. }
  261. //////////////////////////////////////////////////////////////////////////////////////////////
  262. //
  263. //////////////////////////////////////////////////////////////////////////////////////////////
  264. STDMETHODIMP CRegistryKey::SetValue(LPCSTR lpszValueName, const DWORD dwType, const BYTE * lpData, const DWORD dwDataLen)
  265. {
  266. FUNCTION("CRegistryKey::SetValue ()");
  267. DWORD dwActualDataLen;
  268. //
  269. // If there is no currently opened registry key, then GetValue was called unexpectedly
  270. //
  271. if (!m_fKeyOpen)
  272. {
  273. THROW(E_UNEXPECTED);
  274. }
  275. //
  276. // If this value is of type REG_SZ, define the lenght of the string
  277. //
  278. if (REG_SZ == dwType)
  279. {
  280. dwActualDataLen = strlen((LPSTR)lpData) + 1;
  281. if (dwActualDataLen > dwDataLen)
  282. {
  283. dwActualDataLen = dwDataLen - 1;
  284. }
  285. }
  286. else
  287. {
  288. dwActualDataLen = dwDataLen;
  289. }
  290. //
  291. //
  292. // Set the registry value
  293. //
  294. if (ERROR_SUCCESS != RegSetValueEx(m_hRegistryKey, lpszValueName, 0, dwType, lpData, dwActualDataLen))
  295. {
  296. THROW(E_FAIL);
  297. }
  298. return S_OK;
  299. }
  300. //////////////////////////////////////////////////////////////////////////////////////////////
  301. //
  302. //////////////////////////////////////////////////////////////////////////////////////////////
  303. STDMETHODIMP CRegistryKey::DeleteValue(LPCSTR lpszValueName)
  304. {
  305. FUNCTION("CRegistryKey::DeleteValue ()");
  306. //
  307. // If there is no currently opened registry key, then GetValue was called unexpectedly
  308. //
  309. if (!m_fKeyOpen)
  310. {
  311. THROW(E_UNEXPECTED);
  312. }
  313. if (ERROR_SUCCESS != RegDeleteValue(m_hRegistryKey, lpszValueName))
  314. {
  315. THROW(E_FAIL);
  316. }
  317. return S_OK;
  318. }