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.

534 lines
15 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 cbSize = sizeof( szBuffer );
  137. dwStatus_ = RegQueryValueEx( hKey_,
  138. pValueName,
  139. NULL,
  140. &dwType,
  141. reinterpret_cast<LPBYTE>( szBuffer ),
  142. &cbSize );
  143. if( dwStatus_ == ERROR_MORE_DATA && dwType == REG_SZ && cbSize )
  144. {
  145. //
  146. // cbSize is the requested size of the buffer in bytes.
  147. // allocate two more characters - one to make sure the
  148. // cbSize / sizeof(TCHAR) is rounded up properly and one
  149. // for a zero terminator to cover the case where the
  150. // data is not properly zero terminated when written.
  151. //
  152. DWORD cchSize = cbSize / sizeof(TCHAR) + 2;
  153. LPTSTR pszBuff = new TCHAR[ cchSize ];
  154. if( pszBuff )
  155. {
  156. cbSize = cchSize * sizeof(TCHAR);
  157. dwStatus_ = RegQueryValueEx( hKey_,
  158. pValueName,
  159. NULL,
  160. &dwType,
  161. reinterpret_cast<LPBYTE>( pszBuff ),
  162. &cbSize );
  163. }
  164. else
  165. {
  166. dwStatus_ = ERROR_NOT_ENOUGH_MEMORY;
  167. }
  168. if( dwStatus_ == ERROR_SUCCESS )
  169. {
  170. //
  171. // RegQueryValueEx may not zero terminate the buffer if the
  172. // data in the registry is not zero terminated. Make sure it
  173. // is properly zero terminated.
  174. //
  175. pszBuff[cchSize-1] = 0;
  176. bStatus = strValue.bUpdate( pszBuff );
  177. }
  178. delete [] pszBuff;
  179. }
  180. else
  181. {
  182. if( dwStatus_ == ERROR_SUCCESS && dwType == REG_SZ )
  183. {
  184. //
  185. // RegQueryValueEx may not zero terminate the buffer if the
  186. // data in the registry is not zero terminated. Make sure it
  187. // is properly zero terminated.
  188. //
  189. szBuffer[ARRAYSIZE(szBuffer)-1] = 0;
  190. bStatus = strValue.bUpdate( szBuffer );
  191. }
  192. }
  193. return bStatus;
  194. }
  195. BOOL
  196. TPersist::
  197. bRead(
  198. IN LPCTSTR pValueName,
  199. IN OUT PVOID pValue,
  200. IN DWORD cbSize,
  201. IN LPDWORD pcbNeeded OPTIONAL
  202. )
  203. {
  204. SPLASSERT( bValid() );
  205. SPLASSERT( pValueName );
  206. SPLASSERT( pValue );
  207. DWORD dwType = REG_BINARY;
  208. BOOL bStatus = FALSE;
  209. DWORD dwSize = cbSize;
  210. dwStatus_ = RegQueryValueEx( hKey_,
  211. pValueName,
  212. NULL,
  213. &dwType,
  214. reinterpret_cast<LPBYTE>( pValue ),
  215. &dwSize );
  216. if( dwStatus_ == ERROR_MORE_DATA && pcbNeeded )
  217. {
  218. *pcbNeeded = dwSize;
  219. }
  220. return dwStatus_ == ERROR_SUCCESS && dwType == REG_BINARY && dwSize == cbSize;
  221. }
  222. BOOL
  223. TPersist::
  224. bWrite(
  225. IN LPCTSTR pValueName,
  226. IN const DWORD dwValue
  227. )
  228. {
  229. SPLASSERT( bValid() );
  230. SPLASSERT( pValueName );
  231. dwStatus_ = RegSetValueEx( hKey_,
  232. pValueName,
  233. 0,
  234. REG_DWORD,
  235. reinterpret_cast<const BYTE *>( &dwValue ),
  236. sizeof( dwValue ) );
  237. return dwStatus_ == ERROR_SUCCESS;
  238. }
  239. BOOL
  240. TPersist::
  241. bWrite(
  242. IN LPCTSTR pValueName,
  243. IN LPCTSTR pszValue
  244. )
  245. {
  246. SPLASSERT( bValid() );
  247. SPLASSERT( pValueName );
  248. dwStatus_ = RegSetValueEx( hKey_,
  249. pValueName,
  250. 0,
  251. REG_SZ,
  252. reinterpret_cast<const BYTE *>( pszValue ),
  253. _tcslen( pszValue ) * sizeof( TCHAR ) + sizeof( TCHAR ) );
  254. return dwStatus_ == ERROR_SUCCESS;
  255. }
  256. BOOL
  257. TPersist::
  258. bWrite(
  259. IN LPCTSTR pValueName,
  260. IN const PVOID pValue,
  261. IN DWORD cbSize
  262. )
  263. {
  264. SPLASSERT( bValid() );
  265. SPLASSERT( pValueName );
  266. SPLASSERT( pValue );
  267. dwStatus_ = RegSetValueEx( hKey_,
  268. pValueName,
  269. 0,
  270. REG_BINARY,
  271. reinterpret_cast<const BYTE *>( pValue ),
  272. cbSize );
  273. return dwStatus_ == ERROR_SUCCESS;
  274. }
  275. BOOL
  276. TPersist::
  277. bRemove(
  278. IN LPCTSTR pValueName
  279. )
  280. {
  281. SPLASSERT( bValid() );
  282. SPLASSERT( pValueName );
  283. dwStatus_ = RegDeleteValue( hKey_, pValueName );
  284. return dwStatus_ == ERROR_SUCCESS;
  285. }
  286. BOOL
  287. TPersist::
  288. bRemoveKey(
  289. IN LPCTSTR pKeyName
  290. )
  291. {
  292. SPLASSERT( bValid() );
  293. SPLASSERT( pKeyName );
  294. dwStatus_ = dwRecursiveRegDeleteKey( hKey_, pKeyName );
  295. return dwStatus_ == ERROR_SUCCESS;
  296. }
  297. DWORD
  298. TPersist::
  299. dwRecursiveRegDeleteKey(
  300. IN HKEY hKey,
  301. IN LPCTSTR pszSubkey
  302. ) const
  303. {
  304. HKEY hSubkey = NULL;
  305. DWORD dwStatus = RegOpenKeyEx( hKey,
  306. pszSubkey,
  307. 0,
  308. KEY_ALL_ACCESS,
  309. &hSubkey );
  310. while ( dwStatus == ERROR_SUCCESS )
  311. {
  312. TCHAR szSubkey[ MAX_PATH ];
  313. DWORD cbSubkeySize = COUNTOF( szSubkey );
  314. dwStatus = RegEnumKeyEx( hSubkey,
  315. 0,
  316. szSubkey,
  317. &cbSubkeySize,
  318. 0,
  319. 0,
  320. 0,
  321. 0 );
  322. if( dwStatus == ERROR_NO_MORE_ITEMS )
  323. break;
  324. if( dwStatus != ERROR_SUCCESS )
  325. return dwStatus;
  326. dwStatus = dwRecursiveRegDeleteKey( hSubkey, szSubkey );
  327. }
  328. if( hSubkey )
  329. {
  330. RegCloseKey( hSubkey );
  331. }
  332. dwStatus = RegDeleteKey( hKey, pszSubkey );
  333. return dwStatus;
  334. }
  335. #if DBG
  336. VOID
  337. TestPersistClass(
  338. VOID
  339. )
  340. {
  341. TStatusB bStatus;
  342. TString strValue;
  343. DWORD dwValue = 0xDEADBEEF;
  344. LPCTSTR pszValue = TEXT( "TestValueData" );
  345. DWORD cbNeeded = 0;
  346. TCHAR szValue[MAX_PATH];
  347. for( UINT i = 0; i < COUNTOF( szValue )-1; i++ )
  348. szValue[i] = TEXT('A');
  349. szValue[i] = 0;
  350. {
  351. TPersist Persist( TEXT( "Printers\\Settings\\Test" ), TPersist::kCreate|TPersist::kWrite );
  352. if( VALID_OBJ( Persist ) )
  353. {
  354. bStatus DBGCHK = Persist.bWrite( TEXT("Test Value dword"), dwValue );
  355. bStatus DBGCHK = Persist.bWrite( TEXT("Test Value string"), TEXT("Test") );
  356. bStatus DBGCHK = Persist.bWrite( TEXT("Test Value binary"), szValue, sizeof( szValue ) );
  357. }
  358. }
  359. {
  360. TPersist Persist( TEXT( "Printers\\Settings\\Test" ), TPersist::kOpen|TPersist::kRead );
  361. if( VALID_OBJ( Persist ) )
  362. {
  363. bStatus DBGCHK = Persist.bRead( TEXT("Test Value dword"), dwValue );
  364. DBGMSG( DBG_TRACE, ("Test value dword %x\n", dwValue ) );
  365. bStatus DBGCHK = Persist.bRead( TEXT("Test Value string"), strValue );
  366. DBGMSG( DBG_TRACE, ("Test value string " TSTR "\n", (LPCTSTR)strValue ) );
  367. DBGMSG( DBG_TRACE, ("1Test value binary\n" ) );
  368. bStatus DBGCHK = Persist.bRead( TEXT("Test Value binary"), szValue, sizeof( szValue ) - 1 );
  369. if( bStatus )
  370. {
  371. DBGMSG( DBG_TRACE, ("1Test value binary succeeded\n" ) );
  372. DBGMSG( DBG_TRACE, ("-"TSTR"-\n", szValue) );
  373. }
  374. else
  375. {
  376. DBGMSG( DBG_TRACE, ("1Test value binary failed with %d\n", Persist.dwLastError() ) );
  377. }
  378. DBGMSG( DBG_TRACE, ("2Test value binary\n" ) );
  379. bStatus DBGCHK = Persist.bRead( TEXT("Test Value binary"), szValue, sizeof( szValue ) );
  380. if( bStatus )
  381. {
  382. DBGMSG( DBG_TRACE, ("2Test value binary succeeded\n" ) );
  383. DBGMSG( DBG_TRACE, ("-"TSTR"-\n", szValue) );
  384. }
  385. else
  386. {
  387. DBGMSG( DBG_TRACE, ("2Test value binary failed with %d\n", Persist.dwLastError() ) );
  388. }
  389. DBGMSG( DBG_TRACE, ("3Test value binary\n" ) );
  390. bStatus DBGCHK = Persist.bRead( TEXT("Test Value binary"), szValue, sizeof( szValue )-8, &cbNeeded );
  391. if( bStatus )
  392. {
  393. DBGMSG( DBG_TRACE, ("3Test value binary succeeded\n" ) );
  394. DBGMSG( DBG_TRACE, ("-"TSTR"-\n", szValue) );
  395. }
  396. else
  397. {
  398. DBGMSG( DBG_TRACE, ("3Test value binary cbNeeded %d LastError %d\n", cbNeeded, Persist.dwLastError() ) );
  399. }
  400. }
  401. }
  402. {
  403. TPersist Persist( TEXT( "Printers\\Settings\\Test" ), TPersist::kOpen|TPersist::kRead|TPersist::kWrite );
  404. if( VALID_OBJ( Persist ) )
  405. {
  406. bStatus DBGCHK = Persist.bRemove( TEXT("dead") );
  407. if( !bStatus )
  408. DBGMSG( DBG_TRACE, ("Remove of " TSTR " failed LastError %d\n", TEXT("dead"), Persist.dwLastError() ) );
  409. bStatus DBGCHK = Persist.bRemove( TEXT("Test Value dwordx") );
  410. if( !bStatus )
  411. DBGMSG( DBG_TRACE, ("Remove of " TSTR " failed LastError %d\n", TEXT("Test Value dwordx"), Persist.dwLastError() ) );
  412. bStatus DBGCHK = Persist.bRemove( TEXT("Test Value dword") );
  413. if( !bStatus )
  414. DBGMSG( DBG_TRACE, ("Remove of " TSTR " failed LastError %d\n", TEXT("Test Value dword"), Persist.dwLastError() ) );
  415. bStatus DBGCHK = Persist.bRemove( TEXT("Test Value string") );
  416. if( !bStatus )
  417. DBGMSG( DBG_TRACE, ("Remove of " TSTR " failed LastError %d\n", TEXT("Test Value string"), Persist.dwLastError() ) );
  418. bStatus DBGCHK = Persist.bRemove( TEXT("Test Value binary") );
  419. if( !bStatus )
  420. DBGMSG( DBG_TRACE, ("Remove of " TSTR " failed LastError %d\n", TEXT("Test Value binary"), Persist.dwLastError() ) );
  421. bStatus DBGCHK = Persist.bRemoveKey( TEXT("Test") );
  422. if( !bStatus )
  423. DBGMSG( DBG_TRACE, ("Remove key of " TSTR " failed LastError %d\n", TEXT("Test"), Persist.dwLastError() ) );
  424. }
  425. }
  426. {
  427. TPersist Persist( TEXT( "Printers\\Settings" ), TPersist::kOpen|TPersist::kRead|TPersist::kWrite );
  428. if( VALID_OBJ( Persist ) )
  429. {
  430. bStatus DBGCHK = Persist.bRemoveKey( TEXT("Test") );
  431. if( !bStatus )
  432. DBGMSG( DBG_TRACE, ("Remove key of " TSTR " failed LastError %d\n", TEXT("Test"), Persist.dwLastError() ) );
  433. }
  434. }
  435. }
  436. #endif