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.

643 lines
23 KiB

  1. //Copyright (c) 1998 - 1999 Microsoft Corporation
  2. /*--------------------------------------------------------------------------------------------------------
  3. *
  4. * Module Name:
  5. *
  6. * Registry.cpp
  7. *
  8. * Abstract:
  9. *
  10. * Registry.cpp: implementation of the CRegistry class.
  11. * This class helps with registry by allocating memory by itself
  12. * As a result caller must copy the pointer returned by Get functions
  13. * immediately.
  14. *
  15. *
  16. *
  17. * Author:
  18. *
  19. * Makarand Patwardhan - April 9, 1997
  20. *
  21. * -------------------------------------------------------------------------------------------------------*/
  22. #include "stdafx.h"
  23. #include <fwcommon.h> // This must be the first include.
  24. #include "Registry.h"
  25. /*--------------------------------------------------------------------------------------------------------
  26. * Constructor
  27. * -------------------------------------------------------------------------------------------------------*/
  28. CRegistry::CRegistry()
  29. {
  30. m_pMemBlock = NULL;
  31. m_hKey = NULL;
  32. m_iEnumIndex = -1;
  33. m_iEnumValueIndex = -1;
  34. #ifdef DBG
  35. m_dwSizeDebugOnly = 0;
  36. #endif
  37. }
  38. /*--------------------------------------------------------------------------------------------------------
  39. * Destructor
  40. * -------------------------------------------------------------------------------------------------------*/
  41. CRegistry::~CRegistry()
  42. {
  43. if (m_hKey != NULL)
  44. {
  45. RegCloseKey(m_hKey);
  46. m_hKey = NULL;
  47. }
  48. Release();
  49. }
  50. /*--------------------------------------------------------------------------------------------------------
  51. * void Allocate (DWORD dwSize)
  52. * This private function is used for allocating the memory for
  53. * reading registry
  54. * returns the pointer to memory allocated.
  55. * -------------------------------------------------------------------------------------------------------*/
  56. void *CRegistry::Allocate (DWORD dwSize)
  57. {
  58. ASSERT(dwSize != 0);
  59. if (m_pMemBlock)
  60. Release();
  61. m_pMemBlock = new BYTE[dwSize];
  62. #ifdef DBG
  63. // remember the size of the block to be allocated.
  64. m_dwSizeDebugOnly = dwSize;
  65. #endif
  66. return m_pMemBlock;
  67. }
  68. /*--------------------------------------------------------------------------------------------------------
  69. * void Release ()
  70. * This private function is used for releasing internal memory block
  71. * -------------------------------------------------------------------------------------------------------*/
  72. void CRegistry::Release ()
  73. {
  74. if (m_pMemBlock)
  75. {
  76. #ifdef DBG
  77. // fistly fill up the block we allocated previously with garbage.
  78. // so that if anybody is using this block, it is more lilely to
  79. // catch the bug.
  80. ASSERT(m_dwSizeDebugOnly != 0);
  81. FillMemory(m_pMemBlock, m_dwSizeDebugOnly, 'c');
  82. m_dwSizeDebugOnly = 0;
  83. #endif
  84. delete [] m_pMemBlock;
  85. }
  86. m_pMemBlock = 0;
  87. }
  88. ///*--------------------------------------------------------------------------------------------------------
  89. //* DWORD CRegistry::CreateKey(HKEY hKey, LPCTSTR lpSubKey, REGSAM access /*= KEY_ALL_ACCESS*/, DWORD *pDisposition /*= NULL*/, LPSECURITY_ATTRIBUTES lpSecAttr /* = NULL */)
  90. //* opens/creates the key specified. before attempting any operation on any key/value. this function
  91. //* must be called.
  92. //* hKey - hive
  93. //* lpSubKey - Path of the key in the format _T("SYSTEM\\CurrentControlSet\\Control\\Terminal Server")
  94. //* access - access desired. like REG_READ, REG_WRITE..
  95. //* RETURNS error code.
  96. //* -------------------------------------------------------------------------------------------------------*/
  97. DWORD CRegistry::CreateKey(HKEY hKey, LPCTSTR lpSubKey, REGSAM access /*= KEY_ALL_ACCESS*/, DWORD *pDisposition /*= NULL*/, LPSECURITY_ATTRIBUTES lpSecAttr /* = NULL */)
  98. {
  99. ASSERT(lpSubKey);
  100. ASSERT(*lpSubKey != '\\');
  101. // security descriptor should be null or it should be a valid one.
  102. ASSERT(!lpSecAttr || IsValidSecurityDescriptor(lpSecAttr->lpSecurityDescriptor));
  103. ASSERT(lpSubKey);
  104. ASSERT(*lpSubKey != '\\');
  105. if (m_hKey != NULL)
  106. {
  107. RegCloseKey(m_hKey);
  108. m_hKey = NULL;
  109. }
  110. DWORD dwDisposition;
  111. LONG lResult = RegCreateKeyEx(
  112. hKey, // handle of an open key
  113. lpSubKey, // address of subkey name
  114. 0, // reserved
  115. NULL, // address of class string
  116. REG_OPTION_NON_VOLATILE , // special options flag
  117. access, // desired security access
  118. lpSecAttr, // address of key security structure
  119. &m_hKey, // address of buffer for opened handle
  120. &dwDisposition // address of disposition value buffer
  121. );
  122. if (lResult != ERROR_SUCCESS)
  123. {
  124. m_hKey = NULL;
  125. }
  126. if (pDisposition)
  127. *pDisposition = dwDisposition;
  128. return lResult;
  129. }
  130. /*--------------------------------------------------------------------------------------------------------
  131. * DWORD OpenKey(HKEY hKey, LPCTSTR lpSubKey, REGSAM access) ()
  132. * opens the key specified. before attempting any operation on any key/value. this function
  133. * must be called.
  134. * hKey - hive
  135. * lpSubKey - Path of the key in the format _T("SYSTEM\\CurrentControlSet\\Control\\Terminal Server")
  136. * access - access desired. like REG_READ, REG_WRITE..
  137. * RETURNS error code.
  138. * -------------------------------------------------------------------------------------------------------*/
  139. DWORD CRegistry::OpenKey(HKEY hKey, LPCTSTR lpSubKey, REGSAM access /*= KEY_ALL_ACCESS*/ )
  140. {
  141. ASSERT(lpSubKey);
  142. ASSERT(*lpSubKey != '\\');
  143. if (m_hKey != NULL)
  144. {
  145. RegCloseKey(m_hKey);
  146. m_hKey = NULL;
  147. }
  148. LONG lResult = RegOpenKeyEx(
  149. hKey, // handle of open key
  150. lpSubKey, // address of name of subkey to open
  151. 0 , // reserved
  152. access, // security access mask
  153. &m_hKey // address of handle of open key
  154. );
  155. if (lResult != ERROR_SUCCESS)
  156. {
  157. m_hKey = NULL;
  158. }
  159. return lResult;
  160. }
  161. DWORD CRegistry::DeleteValue (LPCTSTR lpValue)
  162. {
  163. ASSERT(lpValue);
  164. ASSERT(m_hKey);
  165. return RegDeleteValue(m_hKey, lpValue);
  166. }
  167. DWORD CRegistry::RecurseDeleteKey (LPCTSTR lpSubKey)
  168. {
  169. ASSERT(lpSubKey);
  170. ASSERT(m_hKey);
  171. CRegistry reg;
  172. DWORD dwError = reg.OpenKey(m_hKey, lpSubKey);
  173. if (dwError != ERROR_SUCCESS)
  174. return dwError;
  175. LPTSTR lpChildKey;
  176. DWORD dwSize;
  177. // we needn't/shouldn't use GetNextSubKey in this here
  178. // as we are deleting the key during the loop.
  179. while (ERROR_SUCCESS == reg.GetFirstSubKey(&lpChildKey, &dwSize))
  180. {
  181. VERIFY(reg.RecurseDeleteKey(lpChildKey) == ERROR_SUCCESS);
  182. }
  183. return RegDeleteKey(m_hKey, lpSubKey);
  184. }
  185. /*--------------------------------------------------------------------------------------------------------
  186. * DWORD ReadReg(LPCTSTR lpValue, LPBYTE *lppbyte, DWORD *pdw, DWORD dwDatatype)
  187. * Reads the registry used internally.
  188. * LPCTSTR lpValue - value to be read.
  189. * LPBYTE *lppbyte - address of the lpbyte at which to place the output buffer.
  190. * DWORD *pdw - address of dword in which size of the buffer (in bytes) is returned.
  191. * dword datatype - datatype you are expecting.
  192. * RETURNS error code.
  193. * -------------------------------------------------------------------------------------------------------*/
  194. DWORD CRegistry::ReadReg(LPCTSTR lpValue, LPBYTE *lppbyte, DWORD *pdw, DWORD dwDatatype)
  195. {
  196. ASSERT(lpValue);
  197. ASSERT(lppbyte);
  198. ASSERT(pdw);
  199. ASSERT(m_hKey != NULL);
  200. *pdw = 0;
  201. DWORD dwType;
  202. DWORD lResult = RegQueryValueEx(
  203. m_hKey, // handle of key to query
  204. lpValue, // address of name of value to query
  205. 0, // reserved
  206. &dwType, // address of buffer for value type
  207. 0, // address of data buffer
  208. pdw // address of data buffer size
  209. );
  210. if (lResult == ERROR_SUCCESS)
  211. {
  212. ASSERT(dwType == dwDatatype || dwType == REG_EXPAND_SZ);
  213. if (0 == Allocate(*pdw))
  214. return ERROR_OUTOFMEMORY;
  215. lResult = RegQueryValueEx(
  216. m_hKey, // handle of key to query
  217. lpValue, // address of name of value to query
  218. 0, // reserved
  219. &dwType, // address of buffer for value type
  220. m_pMemBlock, // address of data buffer
  221. pdw // address of data buffer size
  222. );
  223. ASSERT (ERROR_MORE_DATA != lResult);
  224. if (lResult == ERROR_SUCCESS)
  225. *lppbyte = m_pMemBlock;
  226. }
  227. return lResult;
  228. }
  229. /*--------------------------------------------------------------------------------------------------------
  230. * DWORD ReadRegString(LPCTSTR lpValue, LPTSTR *lppStr, DWORD *pdw)
  231. * Reads A string (REG_SZ) from the registry
  232. * LPCTSTR lpValue value to be read.
  233. * LPTSTR *lppStr - address of LPTSTR in which resultant buffer is returned. caller must copy
  234. * the buffer to immediately. caller must not use this buffer except for copying it.
  235. * caller must not write to this buffer.
  236. * DWORD *pdw - address of dword in which size of the buffer (in bytes) is returned.
  237. * RETURNS error code.
  238. * -------------------------------------------------------------------------------------------------------*/
  239. DWORD CRegistry::ReadRegString(LPCTSTR lpValue, LPTSTR *lppStr, DWORD *pdw)
  240. {
  241. return ReadReg(lpValue, (LPBYTE *)lppStr, pdw, REG_SZ);
  242. }
  243. /*--------------------------------------------------------------------------------------------------------
  244. * DWORD ReadRegDWord(LPCTSTR lpValue, DWORD *pdw)
  245. * Reads A string (REG_SZ) from the registry
  246. * LPCTSTR lpValue value to be read.
  247. * DWORD *pdw - address of dword in which the read dword returned.
  248. * RETURNS error code.
  249. * -------------------------------------------------------------------------------------------------------*/
  250. DWORD CRegistry::ReadRegDWord(LPCTSTR lpValue, DWORD *pdw)
  251. {
  252. ASSERT(pdw);
  253. DWORD dwSize;
  254. LPBYTE pByte;
  255. DWORD dwReturn = ReadReg(lpValue, &pByte, &dwSize, REG_DWORD);
  256. //ASSERT(dwReturn != ERROR_SUCCESS || dwSize == sizeof(DWORD));
  257. if (dwReturn == ERROR_SUCCESS)
  258. *pdw = * LPDWORD(pByte);
  259. return dwReturn;
  260. }
  261. /*--------------------------------------------------------------------------------------------------------
  262. * DWORD ReadRegMultiString(LPCTSTR lpValue, LPTSTR *lppStr, DWORD *pdw)
  263. * Reads A string (REG_MULTI_SZ) from the registry
  264. * LPCTSTR lpValue value to be read.
  265. * LPTSTR *lppStr - address of LPTSTR in which resultant buffer is returned. caller must copy
  266. * the buffer to immediately. caller must not use this buffer except for copying it.
  267. * caller must not write to this buffer.
  268. * DWORD *pdw - address of dword in which size of the buffer (in bytes) is returned.
  269. * RETURNS error code.
  270. * -------------------------------------------------------------------------------------------------------*/
  271. DWORD CRegistry::ReadRegMultiString(LPCTSTR lpValue, LPTSTR *lppStr, DWORD *pdw)
  272. {
  273. return ReadReg(lpValue, (LPBYTE *)lppStr, pdw, REG_MULTI_SZ);
  274. }
  275. /*--------------------------------------------------------------------------------------------------------
  276. * DWORD ReadRegBinary(LPCTSTR lpValue, LPBYTE *lppByte, DWORD *pdw)
  277. * Reads A string (REG_MULTI_SZ) from the registry
  278. * LPCTSTR lpValue value to be read.
  279. * LPBYTE *lppByte - address of LPBYTE in which resultant buffer is returned. caller must copy
  280. * the buffer to immediately. caller must not use this buffer except for copying it.
  281. * caller must not write to this buffer.
  282. * DWORD *pdw - address of dword in which size of the buffer (in bytes) is returned.
  283. * RETURNS error code.
  284. * -------------------------------------------------------------------------------------------------------*/
  285. DWORD CRegistry::ReadRegBinary(LPCTSTR lpValue, LPBYTE *lppByte, DWORD *pdw)
  286. {
  287. return ReadReg(lpValue, lppByte, pdw, REG_BINARY);
  288. }
  289. /*--------------------------------------------------------------------------------------------------------
  290. * DWORD GetFirstSubKey(LPTSTR *lppStr, DWORD *pdw)
  291. * Reads a first subkey for the key
  292. * LPTSTR *lppStr - address of LPTSTR in which resultant buffer is returned. caller must copy
  293. * the buffer to immediately. caller must not use this buffer except for copying it.
  294. * caller must not write to this buffer.
  295. * used to enumerate the registry.
  296. * DWORD *pdw - address of dword in which size of the buffer (in bytes) is returned.
  297. * RETURNS error code.
  298. * -------------------------------------------------------------------------------------------------------*/
  299. DWORD CRegistry::GetFirstSubKey(LPTSTR *lppStr, DWORD *pdw)
  300. {
  301. ASSERT(lppStr);
  302. ASSERT(pdw);
  303. m_iEnumIndex = 0;
  304. return GetNextSubKey(lppStr, pdw);
  305. }
  306. /*--------------------------------------------------------------------------------------------------------
  307. * DWORD GetNextSubKey(LPTSTR *lppStr, DWORD *pdw
  308. * Reads the next subkey for the key
  309. * LPTSTR *lppStr - address of LPTSTR in which resultant buffer is returned. caller must copy
  310. * the buffer to immediately. caller must not use this buffer except for copying it.
  311. * caller must not write to this buffer.
  312. * used to enumerate the registry.
  313. * DWORD *pdw - address of dword in which size of the buffer (in bytes) is returned.
  314. * RETURNS error code.
  315. * -------------------------------------------------------------------------------------------------------*/
  316. DWORD CRegistry::GetNextSubKey(LPTSTR *lppStr, DWORD *pdw)
  317. {
  318. ASSERT(lppStr);
  319. ASSERT(pdw);
  320. ASSERT(m_hKey != NULL);
  321. ASSERT(m_iEnumIndex >= 0); // must call GetFirstSubKey first.
  322. //FILETIME unused;
  323. *pdw = 256;
  324. if (0 == Allocate(*pdw))
  325. return ERROR_NOT_ENOUGH_MEMORY;
  326. LONG lResult = RegEnumKeyEx(
  327. m_hKey, // handle of key to enumerate
  328. m_iEnumIndex, // index of subkey to enumerate
  329. (LPTSTR)m_pMemBlock, // address of buffer for subkey name
  330. pdw, // address for size of subkey buffer
  331. 0, // reserved
  332. NULL, // address of buffer for class string
  333. NULL, // address for size of class buffer
  334. NULL // address for time key last written to
  335. );
  336. (*pdw)++; // since null is not included in the size.
  337. if (ERROR_NO_MORE_ITEMS == lResult)
  338. return lResult;
  339. m_iEnumIndex++;
  340. if (lResult == ERROR_SUCCESS)
  341. *lppStr = (LPTSTR)m_pMemBlock;
  342. return lResult;
  343. }
  344. /*--------------------------------------------------------------------------------------------------------
  345. * DWORD GetFirstValue(LPTSTR *lppStr, DWORD *pdw, DWORD *pDataType)
  346. * Reads a first value for the key
  347. * LPTSTR *lppStr - address of LPTSTR in which resultant buffer is returned. caller must copy
  348. * the buffer to immediately. caller must not use this buffer except for copying it.
  349. * caller must not write to this buffer.
  350. * used to enumerate the registry.
  351. * DWORD *pdw - address of dword in which size of the buffer (in bytes) is returned.
  352. * DWORD *pDataType - datatype of the value is returned in this one.
  353. * RETURNS error code.
  354. * -------------------------------------------------------------------------------------------------------*/
  355. DWORD CRegistry::GetFirstValue(LPTSTR *lppStr, DWORD *pdw, DWORD *pDataType)
  356. {
  357. ASSERT(lppStr);
  358. ASSERT(pdw);
  359. ASSERT(pDataType);
  360. m_iEnumValueIndex = 0;
  361. return GetNextValue(lppStr, pdw, pDataType);
  362. }
  363. /*--------------------------------------------------------------------------------------------------------
  364. * DWORD GetNextValue(LPTSTR *lppStr, DWORD *pdw, DWORD *pDataType)
  365. * Reads a next value for the key
  366. * LPTSTR *lppStr - address of LPTSTR in which resultant buffer is returned. caller must copy
  367. * the buffer to immediately. caller must not use this buffer except for copying it.
  368. * caller must not write to this buffer.
  369. * used to enumerate the registry.
  370. * DWORD *pdw - address of dword in which size of the buffer (in bytes) is returned.
  371. * DWORD *pDataType - datatype of the value is returned in this one.
  372. * RETURNS error code.
  373. * -------------------------------------------------------------------------------------------------------*/
  374. DWORD CRegistry::GetNextValue(LPTSTR *lppStr, DWORD *pdw, DWORD *pDataType)
  375. {
  376. ASSERT(lppStr);
  377. ASSERT(pdw);
  378. ASSERT(pDataType);
  379. ASSERT(m_hKey != NULL);
  380. ASSERT(m_iEnumValueIndex >= 0); // must call GetFirstSubKey first.
  381. *pdw = 256;
  382. if (0 == Allocate(*pdw))
  383. return ERROR_NOT_ENOUGH_MEMORY;
  384. LONG lResult = RegEnumValue(
  385. m_hKey, // handle of key to query
  386. m_iEnumValueIndex, // index of value to query
  387. (LPTSTR)m_pMemBlock, // address of buffer for value string
  388. pdw, // address for size of value buffer
  389. 0, // reserved
  390. pDataType, // address of buffer for type code
  391. NULL, // address of buffer for value data maks_todo : use this
  392. NULL // address for size of data buffer
  393. );
  394. (*pdw)++; // since null is not included in the size.
  395. if (ERROR_NO_MORE_ITEMS == lResult)
  396. return lResult;
  397. m_iEnumValueIndex++;
  398. if (lResult == ERROR_SUCCESS)
  399. *lppStr = (LPTSTR)m_pMemBlock;
  400. return lResult;
  401. }
  402. /*--------------------------------------------------------------------------------------------------------
  403. * DWORD WriteRegString(LPCTSTR lpValueName, LPCTSTR lpStr)
  404. * writes REG_SZ value into the registry
  405. * LPCTSTR lpValueName - value name to be written to
  406. * LPCTSTR lpStr - data to be written
  407. * RETURNS error code.
  408. * -------------------------------------------------------------------------------------------------------*/
  409. DWORD CRegistry::WriteRegString(LPCTSTR lpValueName, LPCTSTR lpStr)
  410. {
  411. ASSERT(m_hKey != NULL); // call setkey before calling this function.
  412. ASSERT(lpValueName);
  413. ASSERT(lpStr);
  414. DWORD dwSize = ( lstrlen(lpStr) + 1) * sizeof(TCHAR) / sizeof(BYTE);
  415. return RegSetValueEx(
  416. m_hKey, // handle of key to set value for
  417. lpValueName, // address of value to set
  418. 0, // Reserved
  419. REG_SZ, // flag for value type
  420. (LPBYTE)lpStr, // address of value data
  421. dwSize // size of value data
  422. );
  423. }
  424. /*--------------------------------------------------------------------------------------------------------
  425. * DWORD WriteRegMultiString(LPCTSTR lpValueName, LPCTSTR lpStr, DWORD dwSize)
  426. * writes REG_MULTI_SZ value into the registry
  427. * LPCTSTR lpValueName - value name to be written to
  428. * LPCTSTR lpStr - data to be written
  429. * DWORD dwSize - size of data.
  430. * RETURNS error code.
  431. * -------------------------------------------------------------------------------------------------------*/
  432. DWORD CRegistry::WriteRegMultiString(LPCTSTR lpValueName, LPCTSTR lpStr, DWORD dwSize)
  433. {
  434. ASSERT(m_hKey != NULL); // call setkey before calling this function.
  435. ASSERT(lpValueName);
  436. ASSERT(lpStr);
  437. #ifdef DBG
  438. // lets make sure that the given size is right.
  439. LPCTSTR lpTemp = lpStr;
  440. DWORD rightsize = 0;
  441. while (lstrlen(lpTemp) > 0)
  442. {
  443. rightsize += lstrlen(lpTemp) + 1;
  444. lpTemp += lstrlen(lpTemp) + 1;
  445. }
  446. ASSERT(*lpTemp == 0); // final NULL.
  447. rightsize++; // account for final terminating null
  448. rightsize *= sizeof(TCHAR) / sizeof(BYTE); // size must be in bytes.
  449. ASSERT(dwSize == rightsize);
  450. #endif
  451. return RegSetValueEx(
  452. m_hKey, // handle of key to set value for
  453. lpValueName, // address of value to set
  454. 0, // Reserved
  455. REG_MULTI_SZ, // flag for value type
  456. (LPBYTE)lpStr, // address of value data
  457. dwSize // size of value data
  458. );
  459. }
  460. /*--------------------------------------------------------------------------------------------------------
  461. * DWORD WriteRegDWord(LPCTSTR lpValueName, DWORD dwValue)
  462. * writes REG_DWORD value into the registry
  463. * LPCTSTR lpValueName - value name to be written to
  464. * LPCTSTR dwValue - data to be written
  465. * RETURNS error code.
  466. * -------------------------------------------------------------------------------------------------------*/
  467. DWORD CRegistry::WriteRegDWord(LPCTSTR lpValueName, DWORD dwValue)
  468. {
  469. ASSERT(m_hKey != NULL); // call setkey before calling this function.
  470. ASSERT(lpValueName);
  471. return RegSetValueEx(
  472. m_hKey, // handle of key to set value for
  473. lpValueName, // address of value to set
  474. 0, // Reserved
  475. REG_DWORD, // flag for value type
  476. (LPBYTE)&dwValue, // address of value data
  477. sizeof(dwValue) // size of value data
  478. );
  479. }
  480. // copy the buffer immediately
  481. DWORD CRegistry::GetSecurity(PSECURITY_DESCRIPTOR *ppSec, SECURITY_INFORMATION SecurityInformation, DWORD *pdwSize)
  482. {
  483. ASSERT(m_hKey != NULL); // call setkey before calling this function.
  484. ASSERT(ppSec);
  485. ASSERT(pdwSize);
  486. DWORD dwError;
  487. PSECURITY_DESCRIPTOR pSecurityDescriptor = NULL;
  488. *pdwSize = 0; // we just want to get the right size during the first call.
  489. dwError = RegGetKeySecurity(
  490. m_hKey, // open handle of key to set
  491. SecurityInformation, // descriptor contents
  492. &pSecurityDescriptor, // address of descriptor for key
  493. pdwSize // address of size of buffer and descriptor
  494. );
  495. // this call can not succeed. as we have set the size = 0
  496. ASSERT(dwError != ERROR_SUCCESS);
  497. if (dwError != ERROR_INSUFFICIENT_BUFFER)
  498. {
  499. // something else has went wronng.
  500. // return the error code
  501. return dwError;
  502. }
  503. ASSERT(*pdwSize != 0);
  504. // now we have got the right size, allocate it.
  505. if (0 == Allocate(*pdwSize))
  506. return ERROR_OUTOFMEMORY;
  507. dwError = RegGetKeySecurity(
  508. m_hKey, // open handle of key to set
  509. SecurityInformation, // descriptor contents
  510. m_pMemBlock, // address of descriptor for key
  511. pdwSize // address of size of buffer and descriptor
  512. );
  513. ASSERT(dwError != ERROR_INSUFFICIENT_BUFFER);
  514. if (dwError == ERROR_SUCCESS)
  515. *ppSec = m_pMemBlock;
  516. return dwError;
  517. }
  518. DWORD CRegistry::SetSecurity(PSECURITY_DESCRIPTOR pSec, SECURITY_INFORMATION SecurityInformation)
  519. {
  520. ASSERT(m_hKey != NULL); // call setkey before calling this function.
  521. return RegSetKeySecurity(
  522. m_hKey, // open handle of key to set
  523. SecurityInformation, // descriptor contents
  524. pSec // address of descriptor for key
  525. );
  526. }
  527. #ifdef _Maks_AutoTest_
  528. //
  529. // make sure that CRegistry does not support
  530. // Copy constructor & assignment operator
  531. //
  532. void TestRegistry (CRegistry reg)
  533. {
  534. CRegistry reg2 = reg; // should get error for copy constructor
  535. CRegistry reg3(reg); // should get error for copy constructor
  536. CRegistry reg4;
  537. reg4 = reg; // should get error for = operator.
  538. TestRegistry(reg); // should get error for copy construtor
  539. }
  540. #endif // _Maks_AutoTest_
  541. // EOF