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.

1012 lines
25 KiB

  1. #include <afxdisp.h> // AfxThrowOleException
  2. #include <objbase.h>
  3. #include <basetyps.h>
  4. #include "dbg.h"
  5. #include "regkey.h"
  6. #include "util.h"
  7. #include "macros.h"
  8. USE_HANDLE_MACROS("GUIDHELP(regkey.cpp)")
  9. using namespace AMC;
  10. DECLARE_INFOLEVEL(AMCCore);
  11. DECLARE_HEAPCHECKING;
  12. // ISSUE-2002/04/01-JonN handle NULL pointer parameters -- omnibus issue
  13. //____________________________________________________________________________
  14. //
  15. // Member: CRegKey::CreateKeyEx
  16. //
  17. // Synopsis: Same meaning as for RegCreateKeyEx API.
  18. //
  19. // Arguments: [hKeyAncestor] -- IN
  20. // [lpszKeyName] -- IN
  21. // [security] -- IN
  22. // [pdwDisposition] -- OUT
  23. // [dwOption] -- IN
  24. // [pSecurityAttributes] -- OUT
  25. //
  26. // Returns: void
  27. //
  28. // History: 5/24/1996 RaviR Created
  29. //____________________________________________________________________________
  30. //
  31. void
  32. CRegKey::CreateKeyEx(
  33. HKEY hKeyAncestor,
  34. LPCTSTR lpszKeyName,
  35. REGSAM security,
  36. DWORD * pdwDisposition,
  37. DWORD dwOption,
  38. LPSECURITY_ATTRIBUTES pSecurityAttributes)
  39. {
  40. ASSERT(lpszKeyName != NULL);
  41. ASSERT(m_hKey == 0); // already called CreateEx on this object
  42. // NTRAID#NTBUG9-654900-2002/07/08-artm initialize dwDisposition
  43. DWORD dwDisposition = 0;
  44. m_lastError = ::RegCreateKeyEx(hKeyAncestor, lpszKeyName, 0, _T(""),
  45. dwOption, security, pSecurityAttributes,
  46. &m_hKey, &dwDisposition);
  47. if (m_lastError != ERROR_SUCCESS)
  48. {
  49. TRACE("CRegKey error %ld creating key \"%s\" under ancestor 0x%x\n",
  50. m_lastError, lpszKeyName, hKeyAncestor );
  51. AfxThrowOleException(PACKAGE_NOT_FOUND);
  52. }
  53. if (pdwDisposition != NULL)
  54. {
  55. *pdwDisposition = dwDisposition;
  56. }
  57. }
  58. //____________________________________________________________________________
  59. //
  60. // Member: CRegKey::OpenKeyEx
  61. //
  62. // Synopsis: Same meaning as RegOpenKeyEx
  63. //
  64. // Arguments: [hKeyAncestor] -- IN
  65. // [lpszKeyName] -- IN
  66. // [security] -- IN
  67. //
  68. // Returns: BOOL (FALSE if key not found, TRUE otherwise.)
  69. //
  70. // History: 6/6/1996 RaviR Created
  71. //
  72. //____________________________________________________________________________
  73. BOOL
  74. CRegKey::OpenKeyEx(
  75. HKEY hKeyAncestor,
  76. LPCTSTR lpszKeyName,
  77. REGSAM security)
  78. {
  79. ASSERT(m_hKey == 0);
  80. m_lastError = ::RegOpenKeyEx(hKeyAncestor, lpszKeyName,
  81. 0, security, &m_hKey);
  82. if (m_lastError == ERROR_SUCCESS)
  83. {
  84. return TRUE;
  85. }
  86. else if (m_lastError != ERROR_FILE_NOT_FOUND)
  87. {
  88. TRACE("CRegKey error %ld opening key \"%s\" under ancestor 0x%x\n",
  89. m_lastError, lpszKeyName, hKeyAncestor );
  90. AfxThrowOleException(PACKAGE_NOT_FOUND);
  91. }
  92. return FALSE;
  93. }
  94. //____________________________________________________________________________
  95. //
  96. // Member: CRegKey::GetKeySecurity
  97. //
  98. // Synopsis: Same meaning as for RegGetKeySecurity API.
  99. //
  100. // Arguments: [SecInf] -- IN descriptor contents
  101. // [pSecDesc] -- OUT address of descriptor for key
  102. // [lpcbSecDesc] -- IN/OUT address of size of buffer for descriptor
  103. //
  104. // Returns: HRESULT.
  105. //
  106. // History: 6/6/1996 RaviR Created
  107. //
  108. //____________________________________________________________________________
  109. //
  110. BOOL
  111. CRegKey::GetKeySecurity(
  112. SECURITY_INFORMATION SecInf,
  113. PSECURITY_DESCRIPTOR pSecDesc,
  114. LPDWORD lpcbSecDesc)
  115. {
  116. ASSERT(pSecDesc != NULL);
  117. ASSERT(lpcbSecDesc != NULL);
  118. ASSERT(m_hKey != NULL);
  119. m_lastError = ::RegGetKeySecurity(m_hKey, SecInf, pSecDesc, lpcbSecDesc);
  120. if (m_lastError == ERROR_SUCCESS)
  121. {
  122. return TRUE;
  123. }
  124. else if (m_lastError != ERROR_INSUFFICIENT_BUFFER)
  125. {
  126. TRACE("CRegKey error %ld reading security of key 0x%x\n",
  127. m_lastError, m_hKey);
  128. AfxThrowOleException(PACKAGE_NOT_FOUND);
  129. }
  130. return FALSE;
  131. }
  132. //____________________________________________________________________________
  133. //
  134. // Member: CRegKey::CloseKey
  135. //
  136. // Synopsis: Same meaning as for RegCloseKey API.
  137. //
  138. // Returns: void
  139. //
  140. // History: 6/6/1996 RaviR Created
  141. //
  142. //____________________________________________________________________________
  143. void
  144. CRegKey::CloseKey()
  145. {
  146. ASSERT(m_hKey != 0);
  147. m_lastError = ::RegCloseKey(m_hKey);
  148. if (m_lastError != ERROR_SUCCESS)
  149. {
  150. TRACE("CRegKey error %ld closing key 0x%x\n",
  151. m_lastError, m_hKey);
  152. AfxThrowOleException(PACKAGE_NOT_FOUND);
  153. }
  154. else
  155. {
  156. // reset the object
  157. m_hKey = 0;
  158. m_lastError = ERROR_SUCCESS;
  159. }
  160. }
  161. //____________________________________________________________________________
  162. //
  163. // Member: CRegKey::DeleteKey
  164. //
  165. // Synopsis: Delete all the keys and subkeys
  166. //
  167. // Arguments: [lpszKeyName] -- IN
  168. //
  169. // Returns: void
  170. //
  171. // History: 6/6/1996 RaviR Created
  172. //
  173. //____________________________________________________________________________
  174. //
  175. void
  176. CRegKey::DeleteKey(
  177. LPCTSTR lpszKeyName)
  178. {
  179. ASSERT(m_hKey != NULL);
  180. ASSERT(lpszKeyName != NULL);
  181. m_lastError = NTRegDeleteKey(m_hKey , lpszKeyName);
  182. if (m_lastError != ERROR_SUCCESS)
  183. {
  184. TRACE("CRegKey error %ld recursively deleting key \"%s\" under key 0x%x\n",
  185. m_lastError, lpszKeyName, m_hKey);
  186. AfxThrowOleException(PACKAGE_NOT_FOUND);
  187. }
  188. }
  189. //____________________________________________________________________________
  190. //
  191. // Member: CRegKey::SetValueEx
  192. //
  193. // Synopsis: Same meaning as for RegSetValueEx API.
  194. //
  195. // Arguments: [lpszValueName] -- IN
  196. // [dwType] -- IN
  197. // [pData] -- OUT
  198. // [nLen] -- IN
  199. //
  200. // Returns: void
  201. //
  202. // History: 6/6/1996 RaviR Created
  203. //
  204. //____________________________________________________________________________
  205. void
  206. CRegKey::SetValueEx(
  207. LPCTSTR lpszValueName,
  208. DWORD dwType,
  209. const void *pData,
  210. DWORD nLen)
  211. {
  212. ASSERT(lpszValueName != NULL);
  213. ASSERT(pData != NULL);
  214. ASSERT(m_hKey != NULL);
  215. #if DBG==1
  216. switch (dwType)
  217. {
  218. case REG_BINARY:
  219. case REG_DWORD:
  220. case REG_DWORD_BIG_ENDIAN:
  221. case REG_EXPAND_SZ:
  222. case REG_LINK:
  223. case REG_MULTI_SZ:
  224. case REG_NONE:
  225. case REG_RESOURCE_LIST:
  226. case REG_SZ:
  227. break;
  228. default:
  229. ASSERT(FALSE); // unknown type
  230. }
  231. #endif
  232. m_lastError = ::RegSetValueEx(m_hKey, lpszValueName, 0, dwType,
  233. (CONST BYTE *)pData, nLen);
  234. if (m_lastError != ERROR_SUCCESS)
  235. {
  236. TRACE("CRegKey error %ld setting value \"%s\" of key 0x%x\n",
  237. m_lastError, lpszValueName, m_hKey);
  238. AfxThrowOleException(PACKAGE_NOT_FOUND);
  239. }
  240. }
  241. //____________________________________________________________________________
  242. //
  243. // Member: IsValuePresent
  244. //
  245. // Arguments: [lpszValueName] -- IN
  246. //
  247. // Returns: BOOL.
  248. //
  249. // History: 3/21/1997 RaviR Created
  250. //____________________________________________________________________________
  251. //
  252. BOOL CRegKey::IsValuePresent(LPCTSTR lpszValueName)
  253. {
  254. DWORD cbData; // ISSUE-2002/04/01-JonN pass NULL for this parameter
  255. m_lastError = ::RegQueryValueEx(m_hKey, lpszValueName, 0, NULL,
  256. NULL, &cbData);
  257. return (m_lastError == ERROR_SUCCESS);
  258. }
  259. //____________________________________________________________________________
  260. //
  261. // Member: CRegKey::QueryValueEx
  262. //
  263. // Synopsis: Same meaning as for RegQueryValueEx API.
  264. //
  265. // Arguments: [lpszValueName] -- IN
  266. // [pType] -- IN
  267. // [pData] -- IN
  268. // [pLen] -- IN
  269. //
  270. // Returns: void
  271. //
  272. // History: 6/6/1996 RaviR Created
  273. //
  274. //____________________________________________________________________________
  275. void
  276. CRegKey::QueryValueEx(
  277. LPCTSTR lpszValueName,
  278. LPDWORD pType,
  279. PVOID pData,
  280. LPDWORD pLen)
  281. {
  282. ASSERT(pLen != NULL);
  283. ASSERT(m_hKey != NULL);
  284. m_lastError = ::RegQueryValueEx(m_hKey, lpszValueName, 0, pType,
  285. (LPBYTE)pData, pLen);
  286. if (m_lastError != ERROR_SUCCESS)
  287. {
  288. TRACE("CRegKey error %d querying data value \"%ws\" of key 0x%x\n",
  289. m_lastError, lpszValueName, m_hKey);
  290. AfxThrowOleException(PACKAGE_NOT_FOUND);
  291. }
  292. }
  293. //____________________________________________________________________________
  294. //
  295. // Member: CRegKey::QueryDword
  296. //
  297. // Synopsis: Query's for DWORD type data.
  298. //
  299. // Arguments: [lpszValueName] -- IN
  300. // [pdwData] -- IN
  301. //
  302. // Returns: void
  303. //
  304. // History: 6/6/1996 RaviR Created
  305. //
  306. //____________________________________________________________________________
  307. void
  308. CRegKey::QueryDword(
  309. LPCTSTR lpszValueName,
  310. LPDWORD pdwData)
  311. {
  312. ASSERT(m_hKey);
  313. DWORD dwType = REG_DWORD;
  314. DWORD dwSize = sizeof(DWORD);
  315. m_lastError = ::RegQueryValueEx(m_hKey, lpszValueName, 0, &dwType,
  316. (LPBYTE)pdwData, &dwSize);
  317. if (m_lastError != ERROR_FILE_NOT_FOUND && dwType != REG_DWORD)
  318. {
  319. m_lastError = ERROR_INVALID_DATATYPE;
  320. }
  321. if (m_lastError != ERROR_SUCCESS)
  322. {
  323. TRACE("CRegKey error %ld querying dword value \"%s\" of key 0x%x\n",
  324. m_lastError, lpszValueName, m_hKey);
  325. AfxThrowOleException(PACKAGE_NOT_FOUND);
  326. }
  327. }
  328. //____________________________________________________________________________
  329. //
  330. // Member: CRegKey::QueryGUID
  331. //
  332. // Synopsis: Query's for GUID type data, stored as REG_SZ.
  333. //
  334. // Arguments: [lpszValueName] -- IN
  335. // [pguid] -- OUT
  336. //
  337. // Returns: void
  338. //
  339. // History: 8/27/1996 JonN Created
  340. //
  341. //____________________________________________________________________________
  342. void
  343. CRegKey::QueryGUID(
  344. LPCTSTR lpszValueName,
  345. GUID* pguid)
  346. {
  347. ASSERT(m_hKey);
  348. ASSERT( NULL != pguid );
  349. CStr str;
  350. QueryString( lpszValueName, str );
  351. // CODEWORK m_lastError should not be HRESULT
  352. m_lastError = GUIDFromCStr( str, pguid );
  353. if (FAILED(m_lastError))
  354. {
  355. TRACE("CRegKey error %ld querying guid value \"%s\" of key 0x%x\n",
  356. m_lastError, lpszValueName, m_hKey);
  357. ////AfxThrowOleException( m_lastError );
  358. }
  359. }
  360. void
  361. CRegKey::SetGUID(
  362. LPCTSTR lpszValueName,
  363. const GUID& guid)
  364. {
  365. ASSERT(m_hKey);
  366. CStr str;
  367. // CODEWORK m_lastError should not be HRESULT
  368. m_lastError = GUIDToCStr( str, guid );
  369. if (FAILED(m_lastError))
  370. {
  371. TRACE("CRegKey error %ld setting guid value \"%s\" of key 0x%x\n",
  372. m_lastError, lpszValueName, m_hKey);
  373. // ISSUE-2002/04/01-JonN should return here?
  374. ////AfxThrowOleException( m_lastError );
  375. }
  376. SetString( lpszValueName, str );
  377. }
  378. //____________________________________________________________________________
  379. //
  380. // Member: CRegKey::QueryString
  381. //
  382. // Synopsis: Query's for string type data.
  383. //
  384. // Arguments: [lpszValueName] -- IN
  385. // [pBuffer] -- OUT
  386. // [pdwBufferByteLen] -- IN/OUT
  387. // [pdwType] -- OUT
  388. //
  389. // Returns: BOOL, returns FALSE if the buffer provided is insufficient.
  390. //
  391. // History: 5/24/1996 RaviR Created
  392. //
  393. //____________________________________________________________________________
  394. BOOL
  395. CRegKey::QueryString(
  396. LPCTSTR lpszValueName,
  397. LPTSTR pBuffer,
  398. DWORD * pdwBufferByteLen,
  399. DWORD * pdwType)
  400. {
  401. ASSERT(pBuffer != NULL);
  402. ASSERT(pdwBufferByteLen != NULL);
  403. ASSERT(m_hKey != NULL);
  404. DWORD dwType = REG_NONE; // JonN 11/21/00 PREFIX 179991
  405. m_lastError = ::RegQueryValueEx(m_hKey, lpszValueName, 0, &dwType,
  406. (LPBYTE)pBuffer, pdwBufferByteLen);
  407. if (pdwType != NULL)
  408. {
  409. *pdwType = dwType;
  410. }
  411. if (m_lastError != ERROR_FILE_NOT_FOUND &&
  412. dwType != REG_SZ && dwType != REG_EXPAND_SZ)
  413. {
  414. m_lastError = ERROR_INVALID_DATATYPE;
  415. }
  416. if (m_lastError == ERROR_SUCCESS)
  417. {
  418. return TRUE;
  419. }
  420. else if (m_lastError != ERROR_MORE_DATA)
  421. {
  422. TRACE("CRegKey error %ld querying bufferstring value \"%s\" of key 0x%x\n",
  423. m_lastError, lpszValueName, m_hKey);
  424. AfxThrowOleException(PACKAGE_NOT_FOUND);
  425. }
  426. return FALSE;
  427. }
  428. //____________________________________________________________________________
  429. //
  430. // Member: CRegKey::QueryString
  431. //
  432. // Synopsis: Query's for string type data.
  433. //
  434. // Arguments: [lpszValueName] -- IN
  435. // [ppStrValue] -- OUT
  436. // [pdwType] -- OUT
  437. //
  438. // Returns: void
  439. //
  440. // History: 6/6/1996 RaviR Created
  441. //
  442. //____________________________________________________________________________
  443. void
  444. CRegKey::QueryString(
  445. LPCTSTR lpszValueName,
  446. LPTSTR * ppStrValue,
  447. DWORD * pdwType)
  448. {
  449. DWORD dwType = REG_SZ;
  450. DWORD dwLen = 0;
  451. // Determine how big the data is
  452. this->QueryValueEx(lpszValueName, &dwType, NULL, &dwLen);
  453. if (pdwType != NULL)
  454. {
  455. *pdwType = dwType;
  456. }
  457. if (dwType != REG_SZ && dwType != REG_EXPAND_SZ)
  458. {
  459. m_lastError = ERROR_INVALID_DATATYPE;
  460. TRACE("CRegKey error %ld querying allocstring value \"%s\" of key 0x%x\n",
  461. m_lastError, lpszValueName, m_hKey);
  462. AfxThrowOleException(PACKAGE_NOT_FOUND);
  463. }
  464. DWORD charLen = dwLen/sizeof(TCHAR);
  465. LPTSTR pBuffer = new TCHAR[charLen + 1];
  466. // ISSUE-2002/04/01-JonN clear buffer
  467. if (dwLen != 0)
  468. {
  469. #if DBG==1
  470. try
  471. {
  472. this->QueryValueEx(lpszValueName, &dwType, pBuffer, &dwLen);
  473. }
  474. catch ( HRESULT result )
  475. {
  476. CHECK_HRESULT( result );
  477. }
  478. #else // ! DBG==1
  479. this->QueryValueEx(lpszValueName, &dwType, pBuffer, &dwLen);
  480. #endif // ! DBG==1
  481. }
  482. pBuffer[charLen] = TEXT('\0');
  483. *ppStrValue = pBuffer;
  484. }
  485. //____________________________________________________________________________
  486. //
  487. // Member: CRegKey::QueryString
  488. //
  489. // Synopsis: Query's for string type data.
  490. //
  491. // Arguments: [lpszValueName] -- IN
  492. // [str] -- OUT
  493. // [pdwType] -- OUT
  494. //
  495. // Returns: void
  496. //
  497. // History: 6/6/1996 RaviR Created
  498. //
  499. //____________________________________________________________________________
  500. void
  501. CRegKey::QueryString(
  502. LPCTSTR lpszValueName,
  503. CStr& str,
  504. DWORD * pdwType)
  505. {
  506. DWORD dwType = REG_SZ;
  507. DWORD dwLen=0;
  508. // Determine how big the data is
  509. this->QueryValueEx(lpszValueName, &dwType, NULL, &dwLen);
  510. if (pdwType != NULL)
  511. {
  512. *pdwType = dwType;
  513. }
  514. if (dwType != REG_SZ && dwType != REG_EXPAND_SZ)
  515. {
  516. m_lastError = ERROR_INVALID_DATATYPE;
  517. TRACE("CRegKey error %ld querying CString value \"%s\" of key 0x%x\n",
  518. m_lastError, lpszValueName, m_hKey);
  519. AfxThrowOleException(PACKAGE_NOT_FOUND);
  520. }
  521. DWORD charLen = dwLen/sizeof(TCHAR);
  522. LPTSTR pBuffer = str.GetBuffer(charLen + 1);
  523. // ISSUE-2002/04/01-JonN clear buffer
  524. if (dwLen != 0)
  525. {
  526. #if DBG==1
  527. try
  528. {
  529. this->QueryValueEx(lpszValueName, &dwType, pBuffer, &dwLen);
  530. }
  531. catch ( HRESULT result )
  532. {
  533. CHECK_HRESULT( result );
  534. }
  535. #else // ! DBG==1
  536. this->QueryValueEx(lpszValueName, &dwType, pBuffer, &dwLen);
  537. #endif // ! DBG==1
  538. }
  539. pBuffer[charLen] = TEXT('\0');
  540. str.ReleaseBuffer();
  541. }
  542. //____________________________________________________________________________
  543. //
  544. // Member: CRegKey::EnumKeyEx
  545. //
  546. // Synopsis: Same meaning as for RegEnumKeyEx API.
  547. //
  548. // Arguments: [iSubkey] -- IN
  549. // [lpszName] -- OUT place to store the name
  550. // [dwLen] -- IN
  551. // [lpszLastModified] -- IN
  552. //
  553. // Returns: BOOL. Returns FALSE if no more items found.
  554. //
  555. // History: 5/22/1996 RaviR Created
  556. //
  557. //____________________________________________________________________________
  558. BOOL
  559. CRegKey::EnumKeyEx(
  560. DWORD iSubkey,
  561. LPTSTR lpszName,
  562. LPDWORD lpcchName,
  563. PFILETIME lpszLastModified)
  564. {
  565. ASSERT(lpszName != NULL);
  566. ASSERT(lpcchName != NULL);
  567. ASSERT(*lpcchName != 0);
  568. ASSERT(m_hKey != NULL); // key probably not opened
  569. m_lastError = ::RegEnumKeyEx(m_hKey, iSubkey, lpszName, lpcchName,
  570. NULL, NULL, NULL, lpszLastModified);
  571. if (m_lastError == ERROR_SUCCESS)
  572. {
  573. return TRUE;
  574. }
  575. else if (m_lastError != ERROR_NO_MORE_ITEMS)
  576. {
  577. TRACE("CRegKey error %ld enumerating child %i of key 0x%x\n",
  578. m_lastError, iSubkey, m_hKey);
  579. AfxThrowOleException(PACKAGE_NOT_FOUND);
  580. }
  581. return FALSE;
  582. }
  583. //____________________________________________________________________________
  584. //
  585. // Member: CRegKey::EnumValue
  586. //
  587. // Synopsis: Same meaning as for RegEnumValue API.
  588. //
  589. // Arguments: [iValue] -- IN
  590. // [lpszValue] -- OUT
  591. // [lpcchValue] -- OUT
  592. // [lpdwType] -- OUT
  593. // [lpbData] -- OUT
  594. // [lpcbData] -- OUT
  595. //
  596. // Returns: HRESULT. Returns ERROR_NO_MORE_ITEMS if no more items found,
  597. // or ERROR_MORE_DATA if the buffer is too small.
  598. //
  599. // History: 6/6/1996 RaviR Created
  600. // 2/20/02 JonN Security Push -- now returns HRESULT
  601. //
  602. //____________________________________________________________________________
  603. HRESULT
  604. CRegKey::EnumValue(
  605. DWORD iValue,
  606. LPTSTR lpszValue,
  607. LPDWORD lpcchValue,
  608. LPDWORD lpdwType,
  609. LPBYTE lpbData,
  610. LPDWORD lpcbData)
  611. {
  612. // JonN 2/20/02 Security Push
  613. if (NULL == m_hKey)
  614. {
  615. ASSERT(FALSE);
  616. return E_FAIL;
  617. }
  618. if ( IsBadWritePtr( lpcchValue, sizeof(DWORD) )
  619. || IsBadWritePtr( lpszValue, (*lpcchValue) * sizeof(TCHAR) ) )
  620. { // lpdwType, lpbData, lpcbData may be NULL
  621. ASSERT(FALSE);
  622. return E_POINTER;
  623. }
  624. m_lastError = ::RegEnumValue(m_hKey, iValue, lpszValue, lpcchValue,
  625. NULL, lpdwType, lpbData, lpcbData);
  626. // JonN 2/20/02 Security Push: handle ERROR_MORE_DATA properly
  627. if ( m_lastError != ERROR_SUCCESS
  628. && m_lastError != ERROR_MORE_DATA
  629. && m_lastError != ERROR_NO_MORE_ITEMS )
  630. {
  631. TRACE("CRegKey error %ld enumerating value %i of key 0x%x\n",
  632. m_lastError, iValue, m_hKey);
  633. AfxThrowOleException(PACKAGE_NOT_FOUND);
  634. }
  635. return m_lastError;
  636. }
  637. //____________________________________________________________________________
  638. //
  639. // Member: CRegKey::SaveKey
  640. //
  641. // Synopsis: Same meaning as for RegSaveKey API.
  642. //
  643. // Arguments: [lpszFile] -- IN filename to save to.
  644. // [lpsa] -- IN security structure
  645. //
  646. // Returns: void
  647. //
  648. // History: 6/6/1996 RaviR Created
  649. //
  650. //____________________________________________________________________________
  651. //
  652. void
  653. CRegKey::SaveKey(
  654. LPCTSTR lpszFile,
  655. LPSECURITY_ATTRIBUTES lpsa)
  656. {
  657. ASSERT(lpszFile != NULL);
  658. ASSERT(m_hKey != NULL);
  659. m_lastError = ::RegSaveKey(m_hKey, lpszFile, lpsa);
  660. if (m_lastError != ERROR_SUCCESS)
  661. {
  662. TRACE("CRegKey error %ld saving key 0x%x to file \"%s\"\n",
  663. m_lastError, m_hKey, lpszFile);
  664. AfxThrowOleException(PACKAGE_NOT_FOUND);
  665. }
  666. }
  667. //____________________________________________________________________________
  668. //
  669. // Member: CRegKey::RestoreKey
  670. //
  671. // Synopsis: Same meaning as for RegRestoreKey API.
  672. //
  673. // Arguments: [lpszFile] -- IN filename containing saved tree
  674. // [fdw] -- IN optional flags
  675. //
  676. // Returns: void
  677. //
  678. // History: 6/6/1996 RaviR Created
  679. //
  680. //____________________________________________________________________________
  681. //
  682. void
  683. CRegKey::RestoreKey(
  684. LPCTSTR lpszFile,
  685. DWORD fdw)
  686. {
  687. ASSERT(lpszFile != NULL);
  688. ASSERT(m_hKey != NULL);
  689. m_lastError = ::RegRestoreKey(m_hKey, lpszFile, fdw);
  690. if (m_lastError != ERROR_SUCCESS)
  691. {
  692. TRACE("CRegKey error %ld restoring key 0x%x from file \"%s\"\n",
  693. m_lastError, m_hKey, lpszFile);
  694. AfxThrowOleException(PACKAGE_NOT_FOUND);
  695. }
  696. }
  697. //____________________________________________________________________________
  698. //
  699. // Member: CRegKey::NTRegDeleteKey, static
  700. //
  701. // Synopsis: Recursively deletes all the sub keys & finally the
  702. // given start key itself.
  703. //
  704. // Arguments: [hStartKey] -- IN
  705. // [pKeyName] -- IN
  706. //
  707. // Returns: LONG.
  708. //
  709. // History: 5/22/1996 RaviR Created
  710. //
  711. //____________________________________________________________________________
  712. LONG
  713. CRegKey::NTRegDeleteKey(
  714. HKEY hStartKey,
  715. LPCTSTR pKeyName)
  716. {
  717. ASSERT(pKeyName != NULL);
  718. ASSERT(*pKeyName != TEXT('\0'));
  719. DWORD dwSubKeyLength;
  720. TCHAR szSubKey[MAX_PATH+2];
  721. HKEY hKey;
  722. LONG lr = ERROR_SUCCESS;
  723. lr = ::RegOpenKeyEx(hStartKey, pKeyName, 0, KEY_ALL_ACCESS, &hKey);
  724. if (lr != ERROR_SUCCESS)
  725. {
  726. return lr;
  727. }
  728. while (lr == ERROR_SUCCESS)
  729. {
  730. dwSubKeyLength = MAX_PATH;
  731. lr = ::RegEnumKeyEx(hKey, 0, szSubKey, &dwSubKeyLength,
  732. NULL, NULL, NULL, NULL);
  733. if (lr == ERROR_NO_MORE_ITEMS)
  734. {
  735. lr = ::RegCloseKey(hKey);
  736. if (lr == ERROR_SUCCESS)
  737. {
  738. lr = ::RegDeleteKey(hStartKey, pKeyName);
  739. break;
  740. }
  741. }
  742. else if (lr == ERROR_SUCCESS)
  743. {
  744. lr = NTRegDeleteKey(hKey, szSubKey);
  745. }
  746. else
  747. {
  748. // Dont reset lr here!
  749. ::RegCloseKey(hKey);
  750. }
  751. }
  752. return lr;
  753. }
  754. ////////////////////////////////////////////////////////////////////////////
  755. //
  756. // CRegKey formerly inline methods
  757. //
  758. CRegKey::CRegKey(HKEY hKey)
  759. :
  760. m_hKey(hKey),
  761. m_lastError(ERROR_SUCCESS)
  762. {
  763. ;
  764. }
  765. CRegKey::~CRegKey()
  766. {
  767. if (m_hKey != NULL)
  768. {
  769. this->CloseKey();
  770. }
  771. }
  772. HKEY CRegKey::AttachKey(HKEY hKey)
  773. {
  774. HKEY hKeyOld = m_hKey;
  775. m_hKey = hKey;
  776. m_lastError = ERROR_SUCCESS;
  777. return hKeyOld;
  778. }
  779. void CRegKey::DeleteValue(LPCTSTR lpszValueName)
  780. {
  781. ASSERT(m_hKey); // Key probably not opened or failed to open
  782. m_lastError = ::RegDeleteValue(m_hKey, lpszValueName);
  783. if (m_lastError != ERROR_SUCCESS)
  784. {
  785. TRACE("CRegKey error %ld deleting value \"%s\" from key 0x%x \n",
  786. m_lastError, lpszValueName, m_hKey);
  787. AfxThrowOleException(PACKAGE_NOT_FOUND);
  788. }
  789. }
  790. void CRegKey::FlushKey(void)
  791. {
  792. ASSERT(m_hKey);
  793. m_lastError = ::RegFlushKey(m_hKey);
  794. if (m_lastError != ERROR_SUCCESS)
  795. {
  796. TRACE("CRegKey error %ld flushing key 0x%x \n",
  797. m_lastError, m_hKey);
  798. AfxThrowOleException(PACKAGE_NOT_FOUND);
  799. }
  800. }
  801. void CRegKey::SetString(LPCTSTR lpszValueName, LPCTSTR lpszString)
  802. {
  803. ASSERT(lpszString);
  804. // NATHAN CHECK
  805. #ifndef UNICODE
  806. //#error This will not work without UNICODE
  807. #endif
  808. this->SetValueEx(lpszValueName, REG_SZ, lpszString, lstrlen(lpszString)*sizeof(TCHAR));
  809. }
  810. void CRegKey::SetString(LPCTSTR lpszValueName, CStr& str)
  811. {
  812. this->SetValueEx(lpszValueName, REG_SZ, (LPCTSTR)str, (DWORD) str.GetLength());
  813. }
  814. void CRegKey::SetDword(LPCTSTR lpszValueName, DWORD dwData)
  815. {
  816. this->SetValueEx(lpszValueName, REG_DWORD, &dwData, sizeof(DWORD));
  817. }
  818. void CRegKey::ConnectRegistry(LPTSTR pszComputerName, HKEY hKey)
  819. {
  820. ASSERT(pszComputerName != NULL);
  821. ASSERT(hKey == HKEY_LOCAL_MACHINE || hKey == HKEY_USERS);
  822. ASSERT(m_hKey == NULL);
  823. m_lastError = ::RegConnectRegistry(pszComputerName, hKey, &m_hKey);
  824. if (m_lastError != ERROR_SUCCESS)
  825. {
  826. TRACE("CRegKey error %ld connecting to key 0x%x on remote machine \"%s\"\n",
  827. m_lastError, m_hKey, pszComputerName);
  828. AfxThrowOleException(PACKAGE_NOT_FOUND);
  829. }
  830. }
  831. void CRegKey::SetKeySecurity(SECURITY_INFORMATION SecInf,
  832. PSECURITY_DESCRIPTOR pSecDesc)
  833. {
  834. ASSERT(pSecDesc != NULL);
  835. ASSERT(m_hKey != NULL);
  836. m_lastError = ::RegSetKeySecurity(m_hKey, SecInf, pSecDesc);
  837. if (m_lastError != ERROR_SUCCESS)
  838. {
  839. TRACE("CRegKey error %ld setting security on key 0x%x \n",
  840. m_lastError, m_hKey);
  841. AfxThrowOleException(PACKAGE_NOT_FOUND);
  842. }
  843. }