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.

514 lines
13 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1997 - 1998
  3. All rights reserved.
  4. Module Name:
  5. persist.cxx
  6. Abstract:
  7. Persistent store class.
  8. Author:
  9. Steve Kiraly (SteveKi) 05/12/97
  10. Revision History:
  11. --*/
  12. #include "precomp.hxx"
  13. #pragma hdrstop
  14. #include "persist.hxx"
  15. /********************************************************************
  16. Persistant store class.
  17. ********************************************************************/
  18. TPersist::
  19. TPersist(
  20. IN LPCTSTR pszSection,
  21. IN UINT ioFlags,
  22. IN HKEY hOpenedKey
  23. ) : strSection_( pszSection ),
  24. hKey_( NULL ),
  25. dwStatus_( ERROR_SUCCESS )
  26. {
  27. SPLASSERT( pszSection );
  28. SPLASSERT( hOpenedKey );
  29. DWORD dwDisposition = 0;
  30. UINT uAccessIndex = 0;
  31. static DWORD adwAccess [] = { 0, KEY_READ, KEY_WRITE, KEY_ALL_ACCESS };
  32. uAccessIndex = ioFlags & ( kRead | kWrite );
  33. if( uAccessIndex )
  34. {
  35. if( ioFlags & kCreate )
  36. {
  37. dwStatus_ = RegCreateKeyEx( hOpenedKey,
  38. strSection_,
  39. 0,
  40. NULL,
  41. 0,
  42. adwAccess[ uAccessIndex ],
  43. NULL,
  44. &hKey_,
  45. &dwDisposition );
  46. }
  47. else if( ioFlags & kOpen )
  48. {
  49. dwStatus_ = RegOpenKeyEx( hOpenedKey,
  50. strSection_,
  51. 0,
  52. adwAccess[ uAccessIndex ],
  53. &hKey_ );
  54. }
  55. }
  56. }
  57. TPersist::
  58. ~TPersist(
  59. VOID
  60. )
  61. {
  62. if( hKey_ )
  63. {
  64. RegCloseKey( hKey_ );
  65. }
  66. }
  67. BOOL
  68. TPersist::
  69. bValid(
  70. VOID
  71. ) const
  72. {
  73. //
  74. // A valid hKey and a valid section name is the class valid check.
  75. //
  76. return hKey_ != NULL && strSection_.bValid();
  77. }
  78. DWORD
  79. TPersist::
  80. dwLastError(
  81. VOID
  82. ) const
  83. {
  84. return dwStatus_;
  85. }
  86. BOOL
  87. TPersist::
  88. bRead(
  89. IN LPCTSTR pValueName,
  90. IN OUT DWORD &dwValue
  91. )
  92. {
  93. SPLASSERT( bValid() );
  94. SPLASSERT( pValueName );
  95. DWORD dwType = REG_DWORD;
  96. DWORD dwSize = sizeof( dwValue );
  97. dwStatus_ = RegQueryValueEx( hKey_,
  98. pValueName,
  99. NULL,
  100. &dwType,
  101. reinterpret_cast<LPBYTE>( &dwValue ),
  102. &dwSize );
  103. return dwStatus_ == ERROR_SUCCESS && dwType == REG_DWORD;
  104. }
  105. BOOL
  106. TPersist::
  107. bRead(
  108. IN LPCTSTR pValueName,
  109. IN OUT BOOL &bValue
  110. )
  111. {
  112. SPLASSERT( bValid() );
  113. SPLASSERT( pValueName );
  114. DWORD dwType = REG_DWORD;
  115. DWORD dwSize = sizeof( bValue );
  116. dwStatus_ = RegQueryValueEx( hKey_,
  117. pValueName,
  118. NULL,
  119. &dwType,
  120. reinterpret_cast<LPBYTE>( &bValue ),
  121. &dwSize );
  122. return dwStatus_ == ERROR_SUCCESS && dwType == REG_DWORD;
  123. }
  124. BOOL
  125. TPersist::
  126. bRead(
  127. IN LPCTSTR pValueName,
  128. IN OUT TString &strValue
  129. )
  130. {
  131. SPLASSERT( bValid() );
  132. SPLASSERT( pValueName );
  133. TCHAR szBuffer[kHint];
  134. DWORD dwType = REG_SZ;
  135. BOOL bStatus = FALSE;
  136. DWORD dwSize = sizeof( szBuffer );
  137. dwStatus_ = RegQueryValueEx( hKey_,
  138. pValueName,
  139. NULL,
  140. &dwType,
  141. reinterpret_cast<LPBYTE>( szBuffer ),
  142. &dwSize );
  143. if( dwStatus_ == ERROR_MORE_DATA && dwType == REG_SZ && dwSize )
  144. {
  145. LPTSTR pszBuff = new TCHAR[ dwSize ];
  146. if( pszBuff )
  147. {
  148. dwStatus_ = RegQueryValueEx( hKey_,
  149. pValueName,
  150. NULL,
  151. &dwType,
  152. reinterpret_cast<LPBYTE>( pszBuff ),
  153. &dwSize );
  154. }
  155. else
  156. {
  157. dwStatus_ = ERROR_NOT_ENOUGH_MEMORY;
  158. }
  159. if( dwStatus_ == ERROR_SUCCESS )
  160. {
  161. bStatus = strValue.bUpdate( pszBuff );
  162. }
  163. delete [] pszBuff;
  164. }
  165. else
  166. {
  167. if( dwStatus_ == ERROR_SUCCESS && dwType == REG_SZ )
  168. {
  169. bStatus = strValue.bUpdate( szBuffer );
  170. }
  171. }
  172. return bStatus;
  173. }
  174. BOOL
  175. TPersist::
  176. bRead(
  177. IN LPCTSTR pValueName,
  178. IN OUT PVOID pValue,
  179. IN DWORD cbSize,
  180. IN LPDWORD pcbNeeded OPTIONAL
  181. )
  182. {
  183. SPLASSERT( bValid() );
  184. SPLASSERT( pValueName );
  185. SPLASSERT( pValue );
  186. DWORD dwType = REG_BINARY;
  187. BOOL bStatus = FALSE;
  188. DWORD dwSize = cbSize;
  189. dwStatus_ = RegQueryValueEx( hKey_,
  190. pValueName,
  191. NULL,
  192. &dwType,
  193. reinterpret_cast<LPBYTE>( pValue ),
  194. &dwSize );
  195. if( dwStatus_ == ERROR_MORE_DATA && pcbNeeded )
  196. {
  197. *pcbNeeded = dwSize;
  198. }
  199. return dwStatus_ == ERROR_SUCCESS && dwType == REG_BINARY && dwSize == cbSize;
  200. }
  201. BOOL
  202. TPersist::
  203. bWrite(
  204. IN LPCTSTR pValueName,
  205. IN const DWORD dwValue
  206. )
  207. {
  208. SPLASSERT( bValid() );
  209. SPLASSERT( pValueName );
  210. dwStatus_ = RegSetValueEx( hKey_,
  211. pValueName,
  212. 0,
  213. REG_DWORD,
  214. reinterpret_cast<const BYTE *>( &dwValue ),
  215. sizeof( dwValue ) );
  216. return dwStatus_ == ERROR_SUCCESS;
  217. }
  218. BOOL
  219. TPersist::
  220. bWrite(
  221. IN LPCTSTR pValueName,
  222. IN LPCTSTR pszValue
  223. )
  224. {
  225. SPLASSERT( bValid() );
  226. SPLASSERT( pValueName );
  227. dwStatus_ = RegSetValueEx( hKey_,
  228. pValueName,
  229. 0,
  230. REG_SZ,
  231. reinterpret_cast<const BYTE *>( pszValue ),
  232. _tcslen( pszValue ) * sizeof( TCHAR ) + sizeof( TCHAR ) );
  233. return dwStatus_ == ERROR_SUCCESS;
  234. }
  235. BOOL
  236. TPersist::
  237. bWrite(
  238. IN LPCTSTR pValueName,
  239. IN const PVOID pValue,
  240. IN DWORD cbSize
  241. )
  242. {
  243. SPLASSERT( bValid() );
  244. SPLASSERT( pValueName );
  245. SPLASSERT( pValue );
  246. dwStatus_ = RegSetValueEx( hKey_,
  247. pValueName,
  248. 0,
  249. REG_BINARY,
  250. reinterpret_cast<const BYTE *>( pValue ),
  251. cbSize );
  252. return dwStatus_ == ERROR_SUCCESS;
  253. }
  254. BOOL
  255. TPersist::
  256. bRemove(
  257. IN LPCTSTR pValueName
  258. )
  259. {
  260. SPLASSERT( bValid() );
  261. SPLASSERT( pValueName );
  262. dwStatus_ = RegDeleteValue( hKey_, pValueName );
  263. return dwStatus_ == ERROR_SUCCESS;
  264. }
  265. BOOL
  266. TPersist::
  267. bRemoveKey(
  268. IN LPCTSTR pKeyName
  269. )
  270. {
  271. SPLASSERT( bValid() );
  272. SPLASSERT( pKeyName );
  273. dwStatus_ = dwRecursiveRegDeleteKey( hKey_, pKeyName );
  274. return dwStatus_ == ERROR_SUCCESS;
  275. }
  276. DWORD
  277. TPersist::
  278. dwRecursiveRegDeleteKey(
  279. IN HKEY hKey,
  280. IN LPCTSTR pszSubkey
  281. ) const
  282. {
  283. HKEY hSubkey = NULL;
  284. DWORD dwStatus = RegOpenKeyEx( hKey,
  285. pszSubkey,
  286. 0,
  287. KEY_ALL_ACCESS,
  288. &hSubkey );
  289. while ( dwStatus == ERROR_SUCCESS )
  290. {
  291. TCHAR szSubkey[ MAX_PATH ];
  292. DWORD cbSubkeySize = COUNTOF( szSubkey );
  293. dwStatus = RegEnumKeyEx( hSubkey,
  294. 0,
  295. szSubkey,
  296. &cbSubkeySize,
  297. 0,
  298. 0,
  299. 0,
  300. 0 );
  301. if( dwStatus == ERROR_NO_MORE_ITEMS )
  302. break;
  303. if( dwStatus != ERROR_SUCCESS )
  304. return dwStatus;
  305. dwStatus = dwRecursiveRegDeleteKey( hSubkey, szSubkey );
  306. }
  307. if( hSubkey )
  308. {
  309. RegCloseKey( hSubkey );
  310. }
  311. dwStatus = RegDeleteKey( hKey, pszSubkey );
  312. return dwStatus;
  313. }
  314. #if DBG
  315. VOID
  316. TestPersistClass(
  317. VOID
  318. )
  319. {
  320. TStatusB bStatus;
  321. TString strValue;
  322. DWORD dwValue = 0xDEADBEEF;
  323. LPCTSTR pszValue = TEXT( "TestValueData" );
  324. DWORD cbNeeded = 0;
  325. TCHAR szValue[MAX_PATH];
  326. for( UINT i = 0; i < COUNTOF( szValue )-1; i++ )
  327. szValue[i] = TEXT('A');
  328. szValue[i] = 0;
  329. {
  330. TPersist Persist( TEXT( "Printers\\Settings\\Test" ), TPersist::kCreate|TPersist::kWrite );
  331. if( VALID_OBJ( Persist ) )
  332. {
  333. bStatus DBGCHK = Persist.bWrite( TEXT("Test Value dword"), dwValue );
  334. bStatus DBGCHK = Persist.bWrite( TEXT("Test Value string"), TEXT("Test") );
  335. bStatus DBGCHK = Persist.bWrite( TEXT("Test Value binary"), szValue, sizeof( szValue ) );
  336. }
  337. }
  338. {
  339. TPersist Persist( TEXT( "Printers\\Settings\\Test" ), TPersist::kOpen|TPersist::kRead );
  340. if( VALID_OBJ( Persist ) )
  341. {
  342. bStatus DBGCHK = Persist.bRead( TEXT("Test Value dword"), dwValue );
  343. DBGMSG( DBG_TRACE, ("Test value dword %x\n", dwValue ) );
  344. bStatus DBGCHK = Persist.bRead( TEXT("Test Value string"), strValue );
  345. DBGMSG( DBG_TRACE, ("Test value string " TSTR "\n", (LPCTSTR)strValue ) );
  346. DBGMSG( DBG_TRACE, ("1Test value binary\n" ) );
  347. bStatus DBGCHK = Persist.bRead( TEXT("Test Value binary"), szValue, sizeof( szValue ) - 1 );
  348. if( bStatus )
  349. {
  350. DBGMSG( DBG_TRACE, ("1Test value binary succeeded\n" ) );
  351. DBGMSG( DBG_TRACE, ("-"TSTR"-\n", szValue) );
  352. }
  353. else
  354. {
  355. DBGMSG( DBG_TRACE, ("1Test value binary failed with %d\n", Persist.dwLastError() ) );
  356. }
  357. DBGMSG( DBG_TRACE, ("2Test value binary\n" ) );
  358. bStatus DBGCHK = Persist.bRead( TEXT("Test Value binary"), szValue, sizeof( szValue ) );
  359. if( bStatus )
  360. {
  361. DBGMSG( DBG_TRACE, ("2Test value binary succeeded\n" ) );
  362. DBGMSG( DBG_TRACE, ("-"TSTR"-\n", szValue) );
  363. }
  364. else
  365. {
  366. DBGMSG( DBG_TRACE, ("2Test value binary failed with %d\n", Persist.dwLastError() ) );
  367. }
  368. DBGMSG( DBG_TRACE, ("3Test value binary\n" ) );
  369. bStatus DBGCHK = Persist.bRead( TEXT("Test Value binary"), szValue, sizeof( szValue )-8, &cbNeeded );
  370. if( bStatus )
  371. {
  372. DBGMSG( DBG_TRACE, ("3Test value binary succeeded\n" ) );
  373. DBGMSG( DBG_TRACE, ("-"TSTR"-\n", szValue) );
  374. }
  375. else
  376. {
  377. DBGMSG( DBG_TRACE, ("3Test value binary cbNeeded %d LastError %d\n", cbNeeded, Persist.dwLastError() ) );
  378. }
  379. }
  380. }
  381. {
  382. TPersist Persist( TEXT( "Printers\\Settings\\Test" ), TPersist::kOpen|TPersist::kRead|TPersist::kWrite );
  383. if( VALID_OBJ( Persist ) )
  384. {
  385. bStatus DBGCHK = Persist.bRemove( TEXT("dead") );
  386. if( !bStatus )
  387. DBGMSG( DBG_TRACE, ("Remove of " TSTR " failed LastError %d\n", TEXT("dead"), Persist.dwLastError() ) );
  388. bStatus DBGCHK = Persist.bRemove( TEXT("Test Value dwordx") );
  389. if( !bStatus )
  390. DBGMSG( DBG_TRACE, ("Remove of " TSTR " failed LastError %d\n", TEXT("Test Value dwordx"), Persist.dwLastError() ) );
  391. bStatus DBGCHK = Persist.bRemove( TEXT("Test Value dword") );
  392. if( !bStatus )
  393. DBGMSG( DBG_TRACE, ("Remove of " TSTR " failed LastError %d\n", TEXT("Test Value dword"), Persist.dwLastError() ) );
  394. bStatus DBGCHK = Persist.bRemove( TEXT("Test Value string") );
  395. if( !bStatus )
  396. DBGMSG( DBG_TRACE, ("Remove of " TSTR " failed LastError %d\n", TEXT("Test Value string"), Persist.dwLastError() ) );
  397. bStatus DBGCHK = Persist.bRemove( TEXT("Test Value binary") );
  398. if( !bStatus )
  399. DBGMSG( DBG_TRACE, ("Remove of " TSTR " failed LastError %d\n", TEXT("Test Value binary"), Persist.dwLastError() ) );
  400. bStatus DBGCHK = Persist.bRemoveKey( TEXT("Test") );
  401. if( !bStatus )
  402. DBGMSG( DBG_TRACE, ("Remove key of " TSTR " failed LastError %d\n", TEXT("Test"), Persist.dwLastError() ) );
  403. }
  404. }
  405. {
  406. TPersist Persist( TEXT( "Printers\\Settings" ), TPersist::kOpen|TPersist::kRead|TPersist::kWrite );
  407. if( VALID_OBJ( Persist ) )
  408. {
  409. bStatus DBGCHK = Persist.bRemoveKey( TEXT("Test") );
  410. if( !bStatus )
  411. DBGMSG( DBG_TRACE, ("Remove key of " TSTR " failed LastError %d\n", TEXT("Test"), Persist.dwLastError() ) );
  412. }
  413. }
  414. }
  415. #endif