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.

406 lines
12 KiB

  1. /*******************************************************************************
  2. *
  3. * (C) COPYRIGHT MICROSOFT CORPORATION, 1998
  4. *
  5. * TITLE: SIMREG.CPP
  6. *
  7. * VERSION: 1.0
  8. *
  9. * AUTHOR: ShaunIv
  10. *
  11. * DATE: 5/12/1998
  12. *
  13. * DESCRIPTION: Simple registry access class
  14. *
  15. *******************************************************************************/
  16. #include "precomp.h"
  17. #pragma hdrstop
  18. #include <simreg.h>
  19. CSimpleReg::CSimpleReg( HKEY hkRoot, const CSimpleString &strSubKey, bool bCreate, REGSAM samDesired, LPSECURITY_ATTRIBUTES lpsa )
  20. : m_strKeyName(strSubKey),
  21. m_hRootKey(hkRoot),
  22. m_hKey(NULL),
  23. m_bCreate(bCreate),
  24. m_lpsaSecurityAttributes(lpsa),
  25. m_samDesiredAccess(samDesired)
  26. {
  27. Open();
  28. }
  29. CSimpleReg::CSimpleReg(void)
  30. : m_strKeyName(TEXT("")),
  31. m_hRootKey(NULL),
  32. m_hKey(NULL),
  33. m_bCreate(false),
  34. m_lpsaSecurityAttributes(NULL),
  35. m_samDesiredAccess(0)
  36. {
  37. }
  38. CSimpleReg::CSimpleReg(const CSimpleReg &other)
  39. : m_strKeyName(other.GetSubKeyName()),
  40. m_hRootKey(other.GetRootKey()),
  41. m_hKey(NULL),
  42. m_bCreate(other.GetCreate()),
  43. m_lpsaSecurityAttributes(other.GetSecurityAttributes()),
  44. m_samDesiredAccess(other.DesiredAccess())
  45. {
  46. Open();
  47. }
  48. CSimpleReg::~CSimpleReg(void)
  49. {
  50. Close();
  51. m_hRootKey = NULL;
  52. m_lpsaSecurityAttributes = NULL;
  53. }
  54. CSimpleReg &CSimpleReg::operator=(const CSimpleReg &other )
  55. {
  56. if (this != &other)
  57. {
  58. Close();
  59. m_strKeyName = other.GetSubKeyName();
  60. m_hRootKey = other.GetRootKey();
  61. m_bCreate = other.GetCreate();
  62. m_lpsaSecurityAttributes = other.GetSecurityAttributes();
  63. m_samDesiredAccess = other.DesiredAccess();
  64. Open();
  65. }
  66. return(*this);
  67. }
  68. bool CSimpleReg::Open(void)
  69. {
  70. HKEY hkKey = NULL;
  71. LONG nRet;
  72. DWORD bCreatedNewKey = 0;
  73. Close();
  74. if (m_bCreate)
  75. nRet = RegCreateKeyEx( m_hRootKey, m_strKeyName.String(), 0, TEXT(""), REG_OPTION_NON_VOLATILE, m_samDesiredAccess?m_samDesiredAccess:KEY_ALL_ACCESS, m_lpsaSecurityAttributes, &hkKey, &bCreatedNewKey );
  76. else nRet = RegOpenKeyEx( m_hRootKey, m_strKeyName.String(), 0, m_samDesiredAccess?m_samDesiredAccess:KEY_ALL_ACCESS, &hkKey );
  77. if (nRet == ERROR_SUCCESS)
  78. m_hKey = hkKey;
  79. return(m_hKey != NULL);
  80. }
  81. bool CSimpleReg::Close(void)
  82. {
  83. __try // In case the key was closed by someone else
  84. {
  85. if (OK())
  86. RegCloseKey(m_hKey);
  87. }
  88. __except( EXCEPTION_EXECUTE_HANDLER )
  89. {
  90. }
  91. m_hKey = NULL;
  92. return(true);
  93. }
  94. bool CSimpleReg::Flush(void)
  95. {
  96. if (!OK())
  97. return(false);
  98. return(ERROR_SUCCESS == RegFlushKey(m_hKey));
  99. }
  100. bool CSimpleReg::IsStringValue( DWORD nType )
  101. {
  102. if (nType != REG_SZ && nType != REG_EXPAND_SZ && nType != REG_MULTI_SZ && nType != REG_LINK && nType != REG_RESOURCE_LIST)
  103. return(false);
  104. else return(true);
  105. }
  106. // Query functions
  107. DWORD CSimpleReg::Size( const CSimpleString &strValueName ) const
  108. {
  109. if (!OK())
  110. return(0);
  111. DWORD nType;
  112. DWORD nSize=0;
  113. LONG Ret = RegQueryValueEx( m_hKey, strValueName.String(), NULL, &nType, NULL, &nSize);
  114. if (Ret==ERROR_SUCCESS)
  115. {
  116. return(nSize);
  117. }
  118. else return (0);
  119. }
  120. DWORD CSimpleReg::Type( const CSimpleString &key ) const
  121. {
  122. if (!OK())
  123. return(0);
  124. DWORD dwType;
  125. DWORD dwSize;
  126. LONG Ret = RegQueryValueEx( m_hKey, key.String(), NULL, &dwType, NULL, &dwSize);
  127. if (Ret==ERROR_SUCCESS)
  128. {
  129. return(dwType);
  130. }
  131. else return(0);
  132. }
  133. CSimpleString CSimpleReg::Query( const CSimpleString &strValueName, const CSimpleString &strDef ) const
  134. {
  135. // If the key is not open, or if this value is not a string type, return the default
  136. if (!OK() || !IsStringValue(Type(strValueName)))
  137. return(strDef);
  138. DWORD nSize = Size(strValueName) / sizeof(TCHAR);
  139. LPTSTR lpszTmp = new TCHAR[nSize];
  140. CSimpleString strTmp;
  141. if (lpszTmp)
  142. {
  143. Query( strValueName, strDef, lpszTmp, nSize );
  144. strTmp = lpszTmp;
  145. delete[] lpszTmp;
  146. }
  147. return(strTmp);
  148. }
  149. LPTSTR CSimpleReg::Query( const CSimpleString &strValueName, const CSimpleString &strDef, LPTSTR pszBuffer, DWORD nLen ) const
  150. {
  151. // If the key is not open, or if this value is not a string type, return the default
  152. if (nLen <= 0 || !OK() || !IsStringValue(Type(strValueName)))
  153. {
  154. lstrcpyn( pszBuffer, strDef.String(), nLen );
  155. pszBuffer[nLen-1] = TEXT('\0');
  156. return(pszBuffer);
  157. }
  158. DWORD nSize = (DWORD)(nLen * sizeof(pszBuffer[0]));
  159. DWORD nType;
  160. LONG nRet = RegQueryValueEx( m_hKey, strValueName.String(), NULL, &nType, (PBYTE)pszBuffer, &nSize);
  161. if (ERROR_SUCCESS != nRet)
  162. {
  163. lstrcpyn( pszBuffer, strDef.String(), nLen );
  164. pszBuffer[nLen-1] = TEXT('\0');
  165. }
  166. return(pszBuffer);
  167. }
  168. DWORD CSimpleReg::Query( const CSimpleString &strValueName, DWORD nDef ) const
  169. {
  170. if (!OK() || (REG_DWORD != Type(strValueName)) || (sizeof(DWORD) != Size(strValueName)))
  171. return(nDef);
  172. DWORD nValue;
  173. DWORD nType;
  174. DWORD nSize = sizeof(DWORD);
  175. LONG nRet;
  176. nRet = RegQueryValueEx( m_hKey, strValueName.String(), NULL, &nType, (PBYTE)&nValue, &nSize);
  177. if (ERROR_SUCCESS == nRet)
  178. return(nValue);
  179. else return(nDef);
  180. }
  181. bool CSimpleReg::Set( const CSimpleString &strValueName, const CSimpleString &strValue, DWORD nType ) const
  182. { // Set a REG_SZ value for the specified key.
  183. if (!OK())
  184. return(false);
  185. LONG nRet;
  186. nRet = RegSetValueEx( m_hKey, strValueName.String(), 0, nType, (PBYTE)strValue.String(), sizeof(strValue[0])*(strValue.Length()+1) );
  187. return(ERROR_SUCCESS==nRet);
  188. }
  189. bool CSimpleReg::Set( const CSimpleString &strValueName, DWORD nValue ) const
  190. { // Set a REG_SZ value for the specified key.
  191. if (!OK())
  192. return(false);
  193. LONG nRet;
  194. nRet = RegSetValueEx( m_hKey, strValueName.String(), 0, REG_DWORD, (PBYTE)&nValue, sizeof(DWORD) );
  195. return(ERROR_SUCCESS==nRet);
  196. }
  197. DWORD CSimpleReg::QueryBin( const CSimpleString &strValueName, PBYTE pData, DWORD nMaxLen ) const
  198. {
  199. if (!OK())
  200. return (0);
  201. if (nMaxLen <= 0)
  202. return (Size(strValueName.String()));
  203. DWORD nType;
  204. DWORD nSize = nMaxLen;
  205. LONG nRet = RegQueryValueEx( m_hKey, strValueName.String(), NULL, &nType, pData, &nSize );
  206. if (ERROR_SUCCESS!=nRet)
  207. return (0);
  208. return (nSize);
  209. }
  210. bool CSimpleReg::SetBin( const CSimpleString &strValueName, const PBYTE pValue, DWORD nLen, DWORD dwType ) const
  211. {
  212. if (!OK())
  213. return(false);
  214. LONG nRet = RegSetValueEx( m_hKey, strValueName.String(), 0, dwType, (PBYTE)pValue, nLen );
  215. return(ERROR_SUCCESS==nRet);
  216. }
  217. DWORD CSimpleReg::SubKeyCount(void) const
  218. {
  219. TCHAR szClass[256]=TEXT("");
  220. DWORD nClassSize = sizeof(szClass)/sizeof(szClass[0]);
  221. DWORD nSubKeyCount=0;
  222. RegQueryInfoKey(m_hKey,szClass,&nClassSize,NULL,&nSubKeyCount,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
  223. return(nSubKeyCount);
  224. }
  225. HKEY CSimpleReg::GetHkeyFromName( const CSimpleString &strName )
  226. {
  227. static const struct
  228. {
  229. LPCTSTR pszName;
  230. HKEY hkKey;
  231. } KeyNames[] =
  232. {
  233. { TEXT("HKEY_CLASSES_ROOT"), HKEY_CLASSES_ROOT},
  234. { TEXT("HKEY_CURRENT_USER"), HKEY_CURRENT_USER},
  235. { TEXT("HKEY_LOCAL_MACHINE"), HKEY_LOCAL_MACHINE},
  236. { TEXT("HKEY_USERS"), HKEY_USERS},
  237. { TEXT("HKEY_CURRENT_CONFIG"), HKEY_CURRENT_CONFIG},
  238. { TEXT("HKEY_DYN_DATA"), HKEY_DYN_DATA},
  239. { TEXT("HKCR"), HKEY_CLASSES_ROOT},
  240. { TEXT("HKCU"), HKEY_CURRENT_USER},
  241. { TEXT("HKLM"), HKEY_LOCAL_MACHINE},
  242. { TEXT("HKU"), HKEY_USERS},
  243. { TEXT("HKCC"), HKEY_CURRENT_CONFIG},
  244. { TEXT("HKDD"), HKEY_DYN_DATA},
  245. { NULL, NULL}
  246. };
  247. for (int i=0;KeyNames[i].pszName;i++)
  248. {
  249. if (!lstrcmpi(strName.String(),KeyNames[i].pszName))
  250. return(KeyNames[i].hkKey);
  251. }
  252. return(NULL);
  253. }
  254. bool CSimpleReg::Delete( HKEY hkRoot, const CSimpleString &strKeyName )
  255. {
  256. return(RegDeleteKey(hkRoot, strKeyName.String()) == ERROR_SUCCESS);
  257. }
  258. bool CSimpleReg::Delete( const CSimpleString &strValue )
  259. {
  260. if (!OK())
  261. return(false);
  262. return(RegDeleteValue( m_hKey, strValue.String() ) == ERROR_SUCCESS);
  263. }
  264. bool CSimpleReg::DeleteRecursively( HKEY hkRoot, const CSimpleString &strKeyName )
  265. {
  266. if (CSimpleReg( hkRoot, strKeyName ).RecurseKeys( DeleteEnumKeyProc, NULL, CSimpleReg::PostOrder ))
  267. return(CSimpleReg::Delete( hkRoot, strKeyName ));
  268. else return(false);
  269. }
  270. bool CSimpleReg::EnumValues( SimRegValueEnumProc enumProc, LPARAM lParam )
  271. {
  272. TCHAR szName[256];
  273. DWORD nSize;
  274. DWORD nType;
  275. bool bResult = true;
  276. for (int i=0;;i++)
  277. {
  278. nSize = sizeof(szName) / sizeof(szName[0]);
  279. if (RegEnumValue(m_hKey,i,szName,&nSize,NULL,&nType,NULL,NULL) != ERROR_SUCCESS)
  280. break;
  281. CValueEnumInfo info(*this,szName,nType,nSize,lParam);
  282. if (enumProc)
  283. {
  284. if (!enumProc(info))
  285. {
  286. bResult = false;
  287. break;
  288. }
  289. }
  290. }
  291. return(bResult);
  292. }
  293. bool CSimpleReg::RecurseKeys( SimRegKeyEnumProc enumProc, LPARAM lParam, int recurseOrder, bool bFailOnOpenError ) const
  294. {
  295. return(DoRecurseKeys(m_hKey, TEXT(""), enumProc, lParam, 0, recurseOrder, bFailOnOpenError ));
  296. }
  297. bool CSimpleReg::EnumKeys( SimRegKeyEnumProc enumProc, LPARAM lParam, bool bFailOnOpenError ) const
  298. {
  299. return(DoEnumKeys(m_hKey, TEXT(""), enumProc, lParam, bFailOnOpenError ));
  300. }
  301. bool CSimpleReg::DoRecurseKeys( HKEY hkKey, const CSimpleString &root, SimRegKeyEnumProc enumProc, LPARAM lParam, int nLevel, int recurseOrder, bool bFailOnOpenError )
  302. {
  303. TCHAR szName[256]=TEXT("");
  304. DWORD nNameSize;
  305. TCHAR szClass[256]=TEXT("");
  306. DWORD nClassSize;
  307. FILETIME ftFileTime;
  308. CSimpleReg reg(hkKey,root);
  309. LONG lRes;
  310. if (!reg.OK())
  311. return(bFailOnOpenError ? false : true);
  312. DWORD nSubKeyCount = reg.SubKeyCount();
  313. for (DWORD i=nSubKeyCount;i>0;i--)
  314. {
  315. nNameSize = sizeof(szName)/sizeof(szName[0]);
  316. nClassSize = sizeof(szClass)/sizeof(szClass[0]);
  317. if ((lRes=RegEnumKeyEx(reg.GetKey(),i-1,szName,&nNameSize,NULL,szClass,&nClassSize,&ftFileTime)) != ERROR_SUCCESS)
  318. {
  319. break;
  320. }
  321. CKeyEnumInfo EnumInfo;
  322. EnumInfo.strName = szName;
  323. EnumInfo.hkRoot = reg.GetKey();
  324. EnumInfo.nLevel = nLevel;
  325. EnumInfo.lParam = lParam;
  326. if (enumProc && recurseOrder==PreOrder)
  327. if (!enumProc(EnumInfo))
  328. return(false);
  329. if (!DoRecurseKeys(reg.GetKey(),szName,enumProc,lParam,nLevel+1,recurseOrder, bFailOnOpenError))
  330. return(false);
  331. if (enumProc && recurseOrder==PostOrder)
  332. if (!enumProc(EnumInfo))
  333. return(false);
  334. }
  335. return(true);
  336. }
  337. bool CSimpleReg::DoEnumKeys( HKEY hkKey, const CSimpleString &root, SimRegKeyEnumProc enumProc, LPARAM lParam, bool bFailOnOpenError )
  338. {
  339. TCHAR szName[256]=TEXT("");
  340. DWORD szNameSize;
  341. TCHAR szClass[256]=TEXT("");
  342. DWORD szClassSize;
  343. FILETIME ftFileTime;
  344. CSimpleReg reg(hkKey,root);
  345. LONG lRes;
  346. if (!reg.OK())
  347. return(bFailOnOpenError ? false : true);
  348. DWORD nSubKeyCount = reg.SubKeyCount();
  349. for (DWORD i=nSubKeyCount;i>0;i--)
  350. {
  351. szNameSize = sizeof(szName)/sizeof(szName[0]);
  352. szClassSize = sizeof(szClass)/sizeof(szClass[0]);
  353. if ((lRes=RegEnumKeyEx(reg.GetKey(),i-1,szName,&szNameSize,NULL,szClass,&szClassSize,&ftFileTime)) != ERROR_SUCCESS)
  354. {
  355. break;
  356. }
  357. CKeyEnumInfo EnumInfo;
  358. EnumInfo.strName = szName;
  359. EnumInfo.hkRoot = reg.GetKey();
  360. EnumInfo.nLevel = 0;
  361. EnumInfo.lParam = lParam;
  362. if (!enumProc(EnumInfo))
  363. return(false);
  364. }
  365. return(true);
  366. }
  367. bool CSimpleReg::DeleteEnumKeyProc( CSimpleReg::CKeyEnumInfo &enumInfo )
  368. {
  369. return(CSimpleReg::Delete( enumInfo.hkRoot, enumInfo.strName ));
  370. }