registry.cpp

Upload User: wangcyou
Upload Date: 2007-01-01
Package Size: 142k
Code Size: 15k
Category: Windows Develop
Development Platform: Visual C++
  1. //---------------------------------------------------------------------------
  2. // Copyright (C) 1998, Interscope Ltd. All rights reserved.
  3. // Reproduction or distribution of this program, or any portion of it, 
  4. // is permitted only if this header is kept as it is.
  5. // For more information, contact:
  6. //
  7. // Interscope Ltd., 5 Culturii St., 5th Floor, 4800 Baia Mare, RO
  8. //    Phone/Fax: +40-62-215023
  9. //    E-mail: office@interscope.ro
  10. //
  11. //   $Author: Levente Farkas $
  12. //     $Date: 5/12/98 11:50p $
  13. //  $Modtime: 4/27/98 6:50a $
  14. // $Revision: 41 $
  15. //  $Archive: /Interscope/Thebe/InstallMaster/Registry.cpp $
  16. // $Workfile: Registry.cpp $
  17. //-----------------------------------------------------------------------
  18. #ifdef __STDAFX__
  19. #include "StdAfx.H"
  20. #endif
  21. #include "Portable.H"
  22. #include "AssertX.H"
  23. #include "Registry.Hpp"
  24. //--- Debugee --------------------------------------------------------------
  25. #ifdef _DEBUG
  26. #undef THIS_FILE
  27. static char THIS_FILE[] = __FILE__;
  28. #ifdef __MFC__
  29. #define new DEBUG_NEW
  30. #endif // __MFC__
  31. #endif // _DEBUG
  32. //--- Miscellaneous -----------------------------------------------------
  33. const int MAX_REG_MACHINE_NAME_LEN  = 50;
  34. //-----------------------------------------------------------------------
  35. // Pre     :
  36. // Post    : 
  37. // Globals :
  38. // I/O     :
  39. // Task    : Create a new registry key object, butdo not attach it 2 any key yet
  40. //-----------------------------------------------------------------------
  41. CRegistry::CRegistry():
  42.            m_hKey(NULL),
  43.            m_bStatus(FALSE)
  44. {
  45. }
  46. //-----------------------------------------------------------------------
  47. // Pre     :
  48. // Post    : Set the status 2 TRUE if opened OK
  49. // Globals :
  50. // I/O     :
  51. // Task    : Open a registry key
  52. //-----------------------------------------------------------------------
  53. CRegistry::CRegistry(HKEY    hKey,         // A previously open key or a section
  54.                      LPCTSTR lpcszSubKey,  // Path relative 2 hKey
  55.                      REGSAM  dwDesiredSecurityAccessMask,        // Desired open/create access
  56.                      BOOL    bAllowCreate,                       // Create new, if does not exist
  57.                      DWORD   dwOptions,                          // New key options
  58.                      LPSECURITY_ATTRIBUTES lpSecurityAttributes, // New key security
  59.                      LPDWORD lpdwDisposition):                   // Cretion disposition (created or opened)
  60.            m_hKey(NULL),
  61.            m_bStatus(FALSE)
  62. {
  63.     Open(hKey,lpcszSubKey,dwDesiredSecurityAccessMask,bAllowCreate,dwOptions,lpSecurityAttributes,lpdwDisposition);
  64. }
  65. //-----------------------------------------------------------------------
  66. // Pre     :
  67. // Post    : Set the status 2 TRUE if opened OK
  68. // Globals :
  69. // I/O     :
  70. // Task    : Open a registry key
  71. //-----------------------------------------------------------------------
  72. BOOL CRegistry::Open(HKEY    hKey,         // A previously open key or a section
  73.                      LPCTSTR lpcszSubKey,  // Path relative 2 hKey
  74.                      REGSAM  dwDesiredSecurityAccessMask,        // Desired open/create access
  75.                      BOOL    bAllowCreate,                       // Create new, if does not exist
  76.                      DWORD   dwOptions,                          // New key options
  77.                      LPSECURITY_ATTRIBUTES lpSecurityAttributes, // New key security
  78.                      LPDWORD lpdwDisposition)                    // Creation disposition (created or opened)
  79. {
  80.     // If already attached 2 a key, close it now
  81.     Close();
  82. #ifdef _DEBUG
  83.     // Store the key's parent and the key's path
  84.     m_hKeyParent =hKey;
  85.     STRNCPY(m_hKeyPath,lpcszSubKey,sizeof(m_hKeyPath)/sizeof(TCHAR));
  86. #endif
  87.     // Attempt 2 open specified key
  88.     m_nErrorCode =RegOpenKeyEx(hKey,lpcszSubKey,0,dwDesiredSecurityAccessMask,&m_hKey);
  89.     if(m_nErrorCode == ERROR_SUCCESS)
  90.     {
  91.         m_bStatus=TRUE;
  92.         if(lpdwDisposition)
  93.             *lpdwDisposition =REG_OPENED_EXISTING_KEY;
  94.     }
  95.     if(!m_bStatus && bAllowCreate)
  96.     {
  97.         // Could not open key, probably inexistent
  98.         // Attempt 2 create it
  99.         DWORD operation;
  100.         m_nErrorCode =RegCreateKeyEx(hKey,lpcszSubKey,0,NULL,dwOptions,dwDesiredSecurityAccessMask,lpSecurityAttributes,&m_hKey,&operation);
  101.         if(m_nErrorCode == ERROR_SUCCESS)
  102.         {
  103.             m_bStatus=TRUE;
  104.             if(lpdwDisposition)
  105.                 *lpdwDisposition =operation;
  106.         }
  107.     }
  108.     return m_bStatus;
  109. }
  110. //---------------------------------------------------------------------------
  111. // Pre     : 
  112. // Post    : Returns size in bytes, -1 on error
  113. // Globals : 
  114. // I/O     : 
  115. // Task    : Get the size of the specified value
  116. //---------------------------------------------------------------------------
  117. DWORD CRegistry::GetValueSize(LPCTSTR name)
  118. {
  119.     if(!m_bStatus)
  120.         return (DWORD)-1;
  121.     DWORD value_size;
  122.     if(!GetValue(name,NULL,value_size))
  123.         return (DWORD)-1;
  124.     return value_size;
  125. }
  126. //-----------------------------------------------------------------------
  127. // Pre     : data_size must be initialized before this call 2 the size of 
  128. //           the buffer where you expect data 2 be returned
  129. // Post    : Return TRUE on success
  130. // Globals :
  131. // I/O     :
  132. // Task    : Extract a value from current key
  133. //-----------------------------------------------------------------------
  134. BOOL CRegistry::GetValue(LPCTSTR name, BYTE *data, DWORD &data_size, DWORD *type)
  135. {
  136.     if(!m_bStatus)
  137.         return FALSE;
  138.     m_nErrorCode=RegQueryValueEx(m_hKey,name,NULL,type,data,&data_size);
  139.     return m_nErrorCode==ERROR_SUCCESS;
  140. }
  141. //-----------------------------------------------------------------------
  142. // Pre     : buffsize must be initialized before this call 2 the size of 
  143. //           the buffer where you expect data 2 be returned
  144. // Post    : Return TRUE on success
  145. // Globals :
  146. // I/O     :
  147. // Task    : Extract default value from current key
  148. //-----------------------------------------------------------------------
  149. BOOL CRegistry::GetDefaultValue(LPTSTR def_value_buff, DWORD &buffsize)
  150. {
  151.     if(!m_bStatus)
  152.         return FALSE;
  153.     m_nErrorCode=RegQueryValueEx(m_hKey,NULL,0,NULL,(BYTE *)def_value_buff,&buffsize);
  154.     return m_nErrorCode==ERROR_SUCCESS;
  155. }
  156. //-----------------------------------------------------------------------
  157. // Pre     :
  158. // Post    : Return TRUE on success
  159. // Globals :
  160. // I/O     :
  161. // Task    : Set a value of the current key
  162. //-----------------------------------------------------------------------
  163. BOOL CRegistry::SetValue(LPCTSTR name, const BYTE *data, DWORD data_size, DWORD type)
  164. {
  165.     if(!m_bStatus)
  166.         return FALSE;
  167.     m_nErrorCode=RegSetValueEx(m_hKey,name,0,type,data,data_size);
  168.     return m_nErrorCode==ERROR_SUCCESS;
  169. }
  170. //-----------------------------------------------------------------------
  171. // Pre     :
  172. // Post    : Return TRUE on success
  173. // Globals :
  174. // I/O     :
  175. // Task    : Set default value of current key
  176. //-----------------------------------------------------------------------
  177. BOOL CRegistry::SetDefaultValue(LPCTSTR def_value)
  178. {
  179.     if(!m_bStatus)
  180.         return FALSE;
  181.     m_nErrorCode=RegSetValueEx(m_hKey,NULL,0,REG_SZ,(BYTE *)def_value,lstrlen(def_value)+1);
  182.     return m_nErrorCode==ERROR_SUCCESS;
  183. }
  184. //-----------------------------------------------------------------------
  185. // Pre     :
  186. // Post    : Return TRUE on success
  187. // Globals :
  188. // I/O     :
  189. // Task    : Deletete specified value of current key
  190. //-----------------------------------------------------------------------
  191. BOOL CRegistry::DeleteValue(LPCTSTR name)
  192. {
  193.     if(!m_bStatus)
  194.         return FALSE;
  195.     m_nErrorCode=RegDeleteValue(m_hKey,name);
  196.     return m_nErrorCode==ERROR_SUCCESS;
  197. }
  198. //-----------------------------------------------------------------------
  199. // Pre     :
  200. // Post    : Return TRUE on success
  201. // Globals :
  202. // I/O     :
  203. // Task    : Enumerate subkeys of the current key
  204. //           You can use this by calling CountSubKeys 2 get the number of 
  205. //           subkeys, then calling this member with 0-based indexes of subkey
  206. //           2 get info about
  207. //-----------------------------------------------------------------------
  208. BOOL CRegistry::EnumerateSubKeys(DWORD index, LPTSTR name, DWORD &name_size)
  209. {
  210.     if(!m_bStatus)
  211.         return FALSE;
  212.     m_nErrorCode=RegEnumKeyEx(m_hKey,index,name,&name_size,NULL,NULL,0,NULL);
  213.     return (m_nErrorCode==ERROR_SUCCESS);
  214. }
  215. //-----------------------------------------------------------------------
  216. // Pre     : If a pointer 2 value data is specified (retrieving value data too)
  217. //           then data_size must not be NULL and the pointed DWORD must hold
  218. //           the size of the data buffer
  219. // Post    : Return TRUE on success
  220. // Globals :
  221. // I/O     :
  222. // Task    : Enumerate values of current key
  223. //           You can use this by calling CountValues 2 get the number of 
  224. //           values, then calling this member with 0-based indexes of value
  225. //           2 get info about
  226. //-----------------------------------------------------------------------
  227. BOOL CRegistry::EnumerateValues(DWORD index, LPTSTR name, DWORD &name_size, DWORD *type, BYTE *data, DWORD *data_size)
  228. {
  229.     if(!m_bStatus)
  230.         return FALSE;
  231.     m_nErrorCode=RegEnumValue(m_hKey,index,name,&name_size,NULL,type,data,data_size);
  232.    return (m_nErrorCode==ERROR_SUCCESS);
  233. }
  234. //-----------------------------------------------------------------------
  235. // Pre     :
  236. // Post    : Return TRUE if info was retrieved OK
  237. // Globals :
  238. // I/O     :
  239. // Task    : Query info about registy key
  240. //-----------------------------------------------------------------------
  241. BOOL CRegistry::GetInfo(LPTSTR  lpszKeyClass, LPDWORD lpcKeyClassSize, // Non-NULL values should be supplied 4 at least
  242.                         LPDWORD lpcSubKeyCount,                        // parameters from one line
  243.                         LPDWORD lpcbLongestSubKeyName,
  244.                         LPDWORD lpcbLargestSubKeyClass,
  245.                         LPDWORD lpcValueCount,
  246.                         LPDWORD lpcbLongestValueName,
  247.                         LPDWORD lpcbLargestValueData,
  248.                         LPDWORD lpcbSecurityDescriptorSize,
  249.                         PFILETIME lpLastWriteTime) // NT only
  250. {
  251. #ifdef _WIN95
  252.     if(lpLastWriteTime)
  253.         ASSERTX(FALSE); // This should be used only on NT, because on Windows 95 it gets filled with 0s
  254. #endif
  255.     if(!m_bStatus)
  256.         return FALSE;
  257.     m_nErrorCode=RegQueryInfoKey(m_hKey,lpszKeyClass,lpcKeyClassSize,NULL,
  258.                                  lpcSubKeyCount,lpcbLongestSubKeyName,lpcbLargestSubKeyClass,
  259.                                  lpcValueCount,lpcbLongestValueName,lpcbLargestValueData,
  260.                                  lpcbSecurityDescriptorSize,
  261.                                  lpLastWriteTime);
  262.     return m_nErrorCode==ERROR_SUCCESS;
  263. }
  264. //-----------------------------------------------------------------------
  265. // Pre     :
  266. // Post    : On error returns -1
  267. // Globals :
  268. // I/O     :
  269. // Task    : Return the number of subkeys of this key
  270. //-----------------------------------------------------------------------
  271. DWORD CRegistry::CountSubKeys()
  272. {
  273.     DWORD subkeys;
  274.     if(!GetInfo(NULL,NULL,&subkeys))
  275.         return (DWORD)-1;
  276.     return subkeys;
  277. }
  278. //-----------------------------------------------------------------------
  279. // Pre     :
  280. // Post    : On error returns FALSE
  281. // Globals :
  282. // I/O     :
  283. // Task    : Remove this key and its descendants
  284. //           Because on NT the key 2 be removed must not have subkeys, remove 
  285. //           first all the subkeys
  286. //-----------------------------------------------------------------------
  287. BOOL CRegistry::Delete(BOOL bDeleteSubkeys)
  288. {
  289.     if(!m_bStatus)
  290.         return FALSE;
  291.     BOOL success =TRUE;
  292.     if(bDeleteSubkeys)
  293.     {
  294.         // Attempt 2 delete all subkeys
  295.         DWORD keys =CountSubKeys();
  296.         while(keys>0)
  297.         {
  298.             TCHAR key_name[MAX_PATH];
  299.             DWORD key_name_size =sizeof(key_name);
  300.             // Get a subkey...
  301.             if(EnumerateSubKeys(0,key_name,key_name_size))
  302.             {
  303.                 // Got a subkey, now delete it
  304.                 CRegistry sub_key(*this,key_name);
  305.                 success =sub_key.Delete();
  306.             }
  307.             if(success)
  308.                 keys =CountSubKeys();
  309.             else
  310.                 break;
  311.         }
  312.     }
  313.     if(success)
  314.     {
  315.         m_nErrorCode=RegDeleteKey(m_hKey,_T(""));
  316.         if(m_nErrorCode==ERROR_SUCCESS)
  317.             Close();
  318.     }
  319.     return success;
  320. }
  321. //-----------------------------------------------------------------------
  322. // Pre     :
  323. // Post    : On error returns -1
  324. // Globals :
  325. // I/O     :
  326. // Task    : Return the number of values in this key
  327. //           This count does not include the default value
  328. //-----------------------------------------------------------------------
  329. DWORD CRegistry::CountValues()
  330. {
  331.     DWORD values;
  332.     if(!GetInfo(NULL,NULL,NULL,NULL,NULL,&values))
  333.         return (DWORD)-1;
  334.     return values;
  335. }
  336. //-----------------------------------------------------------------------
  337. // Pre     :
  338. // Post    : Return TRUE on success
  339. // Globals :
  340. // I/O     :
  341. // Task    : Force saving of registry key data back in the registry
  342. //-----------------------------------------------------------------------
  343. BOOL CRegistry::Flush()
  344. {
  345.     if(!m_bStatus)
  346.         return FALSE;
  347.     m_nErrorCode=RegFlushKey(m_hKey);
  348.     return m_nErrorCode==ERROR_SUCCESS;
  349. }
  350. //-----------------------------------------------------------------------
  351. // Pre     :
  352. // Post    : Return TRUE on success
  353. // Globals :
  354. // I/O     :
  355. // Task    : Conect to a remote computer's HKEY_LOCAL_MACHINE key
  356. //-----------------------------------------------------------------------
  357. BOOL CRegistry::Connect_HKEY_LOCAL_MACHINE(LPCTSTR machine)
  358. {
  359.     Close();
  360.     TCHAR machine_name[MAX_REG_MACHINE_NAME_LEN];
  361.     lstrcpy(machine_name,machine);
  362.     m_nErrorCode=RegConnectRegistry(machine_name,HKEY_LOCAL_MACHINE,&m_hKey);
  363.     if(m_nErrorCode==ERROR_SUCCESS)
  364.         m_bStatus=TRUE;
  365.     else
  366.         m_bStatus=FALSE;
  367.     return m_bStatus;
  368. }
  369. //-----------------------------------------------------------------------
  370. // Pre     :
  371. // Post    : Return TRUE on success
  372. // Globals :
  373. // I/O     :
  374. // Task    : Conect to a remote computer's HKLM key
  375. //-----------------------------------------------------------------------
  376. BOOL CRegistry::Connect_HKEY_USERS(LPCTSTR machine)
  377. {
  378.     Close();
  379.     TCHAR machine_name[MAX_REG_MACHINE_NAME_LEN];
  380.     lstrcpy(machine_name,machine);
  381.     m_nErrorCode=RegConnectRegistry(machine_name,HKEY_USERS,&m_hKey);
  382.     if(m_nErrorCode==ERROR_SUCCESS)
  383.         m_bStatus=TRUE;
  384.     else   
  385.         m_bStatus=FALSE;
  386.     return m_bStatus;
  387. }
  388. //-----------------------------------------------------------------------
  389. // Pre     :
  390. // Post    :
  391. // Globals :
  392. // I/O     :
  393. // Task    : Close key
  394. //-----------------------------------------------------------------------
  395. void CRegistry::Close()
  396. {
  397.     if(m_bStatus)
  398.         RegCloseKey(m_hKey);
  399.     m_hKey    =NULL;
  400.     m_bStatus =FALSE;
  401. }
  402. //-----------------------------------------------------------------------
  403. // Pre     :
  404. // Post    :
  405. // Globals :
  406. // I/O     :
  407. // Task    : Close registry key before destruction
  408. //-----------------------------------------------------------------------
  409. CRegistry::~CRegistry()
  410. {
  411.     Close();
  412. }