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.

890 lines
21 KiB

  1. //
  2. // System level IO verification configuration utility
  3. // Copyright (c) Microsoft Corporation, 1999
  4. //
  5. //
  6. // module: regutil.cxx
  7. // author: DMihai
  8. // created: 04/19/99
  9. // description: registry keys manipulation routines
  10. //
  11. extern "C" {
  12. #include "nt.h"
  13. #include "ntrtl.h"
  14. #include "nturtl.h"
  15. }
  16. #include <windows.h>
  17. #include <tchar.h>
  18. #include <stdlib.h>
  19. #include "ResId.hxx"
  20. #include "ResUtil.hxx"
  21. #include "RegUtil.hxx"
  22. #define VRF_MAX_DRIVER_STRING_LENGTH 4196
  23. //////////////////////////////////////////////////////////////////////
  24. ///////////////////////////////////////////////////// Registry Strings
  25. //////////////////////////////////////////////////////////////////////
  26. LPCTSTR RegMemoryManagementKeyName =
  27. TEXT ("System\\CurrentControlSet\\Control\\Session Manager\\Memory Management");
  28. LPCTSTR RegMmVerifyDriverLevelValueName =
  29. TEXT ("VerifyDriverLevel");
  30. LPCTSTR RegVerifyDriversValueName =
  31. TEXT ("VerifyDrivers");
  32. LPCTSTR RegSessionManagerKeyName =
  33. TEXT ("System\\CurrentControlSet\\Control\\Session Manager");
  34. LPCTSTR RegIOVerifyKeyName =
  35. TEXT ("System\\CurrentControlSet\\Control\\Session Manager\\I/O System");
  36. LPCTSTR RegIOVerifySubKeyName =
  37. TEXT ("I/O System");
  38. LPCTSTR RegIOVerifyLevelValueName =
  39. TEXT ("IoVerifierLevel");
  40. //////////////////////////////////////////////////////////////////////
  41. /////////////// Forward decl for local registry manipulation functions
  42. //////////////////////////////////////////////////////////////////////
  43. BOOL
  44. ReadRegistryValue (
  45. HKEY hKey,
  46. LPCTSTR Name,
  47. DWORD * Value);
  48. BOOL
  49. WriteRegistryValue (
  50. HKEY hKey,
  51. LPCTSTR Name,
  52. DWORD Value);
  53. BOOL
  54. ReadRegistryString (
  55. HKEY hKey,
  56. LPCTSTR Name,
  57. LPTSTR Buffer,
  58. DWORD BufferSize );
  59. BOOL
  60. WriteRegistryString (
  61. HKEY hKey,
  62. LPCTSTR Name,
  63. LPTSTR Value);
  64. BOOL
  65. IsKernelVerifierEnabled( HKEY MmKey );
  66. //////////////////////////////////////////////////////////////////////
  67. ///////////////////////////////////////////////////// Public functions
  68. //////////////////////////////////////////////////////////////////////
  69. void
  70. EnableSysIoVerifier(
  71. DWORD dwNewVerifierLevel )
  72. {
  73. HKEY MmKey = NULL;
  74. HKEY IoKey = NULL;
  75. HKEY SmKey = NULL;
  76. DWORD dwExitCode;
  77. DWORD dwCrtFlags;
  78. DWORD dwCrtSysVerifierLevel;
  79. LONG lResult;
  80. dwExitCode = EXIT_CODE_NOTHING_CHANGED;
  81. //
  82. // Open the Mm key
  83. //
  84. lResult = RegOpenKeyEx (
  85. HKEY_LOCAL_MACHINE,
  86. RegMemoryManagementKeyName,
  87. 0,
  88. KEY_QUERY_VALUE | KEY_WRITE,
  89. &MmKey);
  90. if (lResult != ERROR_SUCCESS)
  91. {
  92. dwExitCode = EXIT_CODE_ERROR;
  93. if( lResult == ERROR_ACCESS_DENIED )
  94. {
  95. DisplayErrorMessage( IDS_ACCESS_IS_DENIED );
  96. }
  97. else
  98. {
  99. DisplayErrorMessage(
  100. IDS_REGOPENKEYEX_FAILED,
  101. RegMemoryManagementKeyName,
  102. (DWORD)lResult);
  103. }
  104. }
  105. else
  106. {
  107. if( IsKernelVerifierEnabled( MmKey ) )
  108. {
  109. //
  110. // must disable kernel verifier first
  111. //
  112. dwExitCode = EXIT_CODE_ERROR;
  113. DisplayErrorMessage( IDS_KVERIFY_ENABLED );
  114. }
  115. else
  116. {
  117. //
  118. // Open the "I/O System" key
  119. //
  120. lResult = RegOpenKeyEx (
  121. HKEY_LOCAL_MACHINE,
  122. RegIOVerifyKeyName,
  123. 0,
  124. KEY_QUERY_VALUE | KEY_WRITE,
  125. &IoKey);
  126. if( lResult != ERROR_SUCCESS )
  127. {
  128. dwExitCode = EXIT_CODE_ERROR;
  129. if( lResult == ERROR_ACCESS_DENIED )
  130. {
  131. //
  132. // access is denied
  133. //
  134. DisplayErrorMessage( IDS_ACCESS_IS_DENIED );
  135. }
  136. else
  137. {
  138. if( lResult == ERROR_FILE_NOT_FOUND )
  139. {
  140. //
  141. // the "I/O System" key doesn't exist, try to create it
  142. //
  143. //
  144. // open the "Session Manager" key
  145. //
  146. lResult = RegOpenKeyEx (
  147. HKEY_LOCAL_MACHINE,
  148. RegSessionManagerKeyName,
  149. 0,
  150. KEY_QUERY_VALUE | KEY_WRITE,
  151. &SmKey);
  152. if( lResult != ERROR_SUCCESS )
  153. {
  154. DisplayErrorMessage(
  155. IDS_REGOPENKEYEX_FAILED,
  156. RegSessionManagerKeyName,
  157. (DWORD)lResult);
  158. }
  159. else
  160. {
  161. //
  162. // create the "I/O System" key
  163. //
  164. lResult = RegCreateKeyEx(
  165. SmKey,
  166. RegIOVerifySubKeyName,
  167. 0,
  168. NULL,
  169. REG_OPTION_NON_VOLATILE,
  170. KEY_WRITE | KEY_QUERY_VALUE,
  171. NULL,
  172. &IoKey,
  173. NULL );
  174. if( lResult != ERROR_SUCCESS )
  175. {
  176. DisplayErrorMessage(
  177. IDS_REGCREATEKEYEX_FAILED,
  178. RegIOVerifySubKeyName,
  179. (DWORD)lResult);
  180. }
  181. else
  182. {
  183. //
  184. // recover from RegOpenKeyEx failure - reset the error code
  185. //
  186. dwExitCode = EXIT_CODE_NOTHING_CHANGED;
  187. }
  188. //
  189. // close the "Session Manager" key
  190. //
  191. lResult = RegCloseKey(
  192. SmKey );
  193. }
  194. }
  195. else
  196. {
  197. //
  198. // other error opening the "I/O System" key
  199. //
  200. DisplayErrorMessage(
  201. IDS_REGOPENKEYEX_FAILED,
  202. RegIOVerifyKeyName,
  203. (DWORD)lResult);
  204. }
  205. }
  206. }
  207. if( dwExitCode != EXIT_CODE_ERROR )
  208. {
  209. //
  210. // read "Mm\VerifyDriverLevel" value
  211. //
  212. if( ReadRegistryValue( MmKey, RegMmVerifyDriverLevelValueName, &dwCrtFlags ) == FALSE )
  213. {
  214. dwExitCode = EXIT_CODE_ERROR;
  215. }
  216. else
  217. {
  218. if( dwCrtFlags == -1 )
  219. {
  220. //
  221. // could not find the value
  222. //
  223. dwCrtFlags = 0;
  224. }
  225. if( ( dwCrtFlags & DRIVER_VERIFIER_IO_CHECKING ) == 0 )
  226. {
  227. //
  228. // set DRIVER_VERIFIER_IO_CHECKING bit in "Mm\VerifyDriverLevel" value
  229. //
  230. dwCrtFlags |= DRIVER_VERIFIER_IO_CHECKING ;
  231. if( WriteRegistryValue( MmKey, RegMmVerifyDriverLevelValueName, dwCrtFlags ) == FALSE )
  232. {
  233. //
  234. // cannot recover from this
  235. //
  236. dwExitCode = EXIT_CODE_ERROR;
  237. }
  238. else
  239. {
  240. dwExitCode = EXIT_CODE_REBOOT;
  241. }
  242. }
  243. }
  244. if( dwExitCode != EXIT_CODE_ERROR )
  245. {
  246. if( ReadRegistryValue( IoKey, RegIOVerifyLevelValueName, &dwCrtSysVerifierLevel ) == FALSE )
  247. {
  248. dwExitCode = EXIT_CODE_ERROR;
  249. }
  250. else
  251. {
  252. if( dwCrtSysVerifierLevel != dwNewVerifierLevel )
  253. {
  254. //
  255. // set "I/O System\IoVerifierLevel" value
  256. //
  257. if( WriteRegistryValue( IoKey, RegIOVerifyLevelValueName, dwNewVerifierLevel ) == FALSE )
  258. {
  259. //
  260. // cannot recover from this
  261. //
  262. dwExitCode = EXIT_CODE_ERROR;
  263. }
  264. else
  265. {
  266. dwExitCode = EXIT_CODE_REBOOT;
  267. }
  268. }
  269. }
  270. }
  271. RegCloseKey (IoKey);
  272. }
  273. }
  274. RegCloseKey (MmKey);
  275. }
  276. if( EXIT_CODE_REBOOT == dwExitCode )
  277. {
  278. DisplayErrorMessage( IDS_MUST_REBOOT );
  279. }
  280. else
  281. {
  282. if( EXIT_CODE_NOTHING_CHANGED == dwExitCode )
  283. {
  284. DisplayErrorMessage( IDS_NOTHING_CHANGED );
  285. }
  286. }
  287. exit( dwExitCode );
  288. }
  289. ///////////////////////////////////////////////////////////////////
  290. void
  291. DisableSysIoVerifier( void )
  292. {
  293. HKEY MmKey = NULL;
  294. HKEY IoKey = NULL;
  295. DWORD dwExitCode;
  296. DWORD dwCrtFlags;
  297. LONG lResult;
  298. dwExitCode = EXIT_CODE_NOTHING_CHANGED;
  299. //
  300. // Open the Mm key
  301. //
  302. lResult = RegOpenKeyEx (
  303. HKEY_LOCAL_MACHINE,
  304. RegMemoryManagementKeyName,
  305. 0,
  306. KEY_QUERY_VALUE | KEY_WRITE,
  307. &MmKey);
  308. if (lResult != ERROR_SUCCESS)
  309. {
  310. dwExitCode = EXIT_CODE_ERROR;
  311. if( lResult == ERROR_ACCESS_DENIED )
  312. {
  313. DisplayErrorMessage( IDS_ACCESS_IS_DENIED );
  314. }
  315. else
  316. {
  317. DisplayErrorMessage(
  318. IDS_REGOPENKEYEX_FAILED,
  319. RegMemoryManagementKeyName,
  320. (DWORD)lResult);
  321. }
  322. }
  323. else
  324. {
  325. //
  326. // read "Mm\VerifyDriverLevel" value
  327. //
  328. if( ReadRegistryValue( MmKey, RegMmVerifyDriverLevelValueName, &dwCrtFlags ) == FALSE )
  329. {
  330. dwExitCode = EXIT_CODE_ERROR;
  331. }
  332. else
  333. {
  334. if( ( dwCrtFlags != -1 ) &&
  335. ( ( dwCrtFlags & DRIVER_VERIFIER_IO_CHECKING ) != 0 ) )
  336. {
  337. //
  338. // wipe out the DRIVER_VERIFIER_IO_CHECKING flag
  339. //
  340. dwCrtFlags &= ~DRIVER_VERIFIER_IO_CHECKING;
  341. if( WriteRegistryValue( MmKey, RegMmVerifyDriverLevelValueName, dwCrtFlags ) == FALSE )
  342. {
  343. //
  344. // cannot recover from this
  345. //
  346. dwExitCode = EXIT_CODE_ERROR;
  347. }
  348. else
  349. {
  350. dwExitCode = EXIT_CODE_REBOOT;
  351. }
  352. }
  353. }
  354. RegCloseKey (MmKey);
  355. }
  356. if( dwExitCode != EXIT_CODE_ERROR )
  357. {
  358. //
  359. // open the "I/O" key
  360. //
  361. lResult = RegOpenKeyEx (
  362. HKEY_LOCAL_MACHINE,
  363. RegIOVerifyKeyName,
  364. 0,
  365. KEY_QUERY_VALUE | KEY_WRITE,
  366. &IoKey);
  367. if (lResult != ERROR_SUCCESS)
  368. {
  369. if( lResult != ERROR_FILE_NOT_FOUND )
  370. {
  371. dwExitCode = EXIT_CODE_ERROR;
  372. if( lResult == ERROR_ACCESS_DENIED )
  373. {
  374. DisplayErrorMessage( IDS_ACCESS_IS_DENIED );
  375. }
  376. else
  377. {
  378. DisplayErrorMessage(
  379. IDS_REGOPENKEYEX_FAILED,
  380. RegIOVerifyKeyName,
  381. (DWORD)lResult);
  382. }
  383. }
  384. }
  385. else
  386. {
  387. //
  388. // delete "I/O System\IoVerifierLevel" value
  389. //
  390. lResult = RegDeleteValue(
  391. IoKey,
  392. RegIOVerifyLevelValueName );
  393. if( lResult != ERROR_SUCCESS && lResult != ERROR_FILE_NOT_FOUND )
  394. {
  395. dwExitCode = EXIT_CODE_ERROR;
  396. DisplayErrorMessage(
  397. IDS_REGDELETEVALUE_FAILED,
  398. RegIOVerifyLevelValueName,
  399. (DWORD)lResult);
  400. }
  401. RegCloseKey (IoKey);
  402. }
  403. }
  404. if( EXIT_CODE_REBOOT == dwExitCode )
  405. {
  406. DisplayErrorMessage( IDS_MUST_REBOOT );
  407. }
  408. else
  409. {
  410. if( EXIT_CODE_NOTHING_CHANGED == dwExitCode )
  411. {
  412. DisplayErrorMessage( IDS_NOTHING_CHANGED );
  413. }
  414. }
  415. exit( dwExitCode );
  416. }
  417. //////////////////////////////////////////////////
  418. void
  419. DumpSysIoVerifierStatus( void )
  420. {
  421. HKEY MmKey = NULL;
  422. HKEY IoKey = NULL;
  423. DWORD dwExitCode;
  424. DWORD dwCrtFlags;
  425. DWORD dwCrtSysVerifLevel;
  426. LONG lResult;
  427. BOOL bMmFlagIsSet = FALSE;
  428. dwExitCode = EXIT_CODE_NOTHING_CHANGED;
  429. //
  430. // Open the Mm key
  431. //
  432. lResult = RegOpenKeyEx (
  433. HKEY_LOCAL_MACHINE,
  434. RegMemoryManagementKeyName,
  435. 0,
  436. KEY_QUERY_VALUE,
  437. &MmKey);
  438. if (lResult != ERROR_SUCCESS)
  439. {
  440. if( lResult != ERROR_FILE_NOT_FOUND )
  441. {
  442. dwExitCode = EXIT_CODE_ERROR;
  443. if( lResult == ERROR_ACCESS_DENIED )
  444. {
  445. DisplayErrorMessage( IDS_ACCESS_IS_DENIED );
  446. }
  447. else
  448. {
  449. DisplayErrorMessage(
  450. IDS_REGOPENKEYEX_FAILED,
  451. RegMemoryManagementKeyName,
  452. (DWORD)lResult);
  453. }
  454. }
  455. }
  456. else
  457. {
  458. //
  459. // read "Mm\VerifyDriverLevel" value
  460. //
  461. if( ReadRegistryValue( MmKey, RegMmVerifyDriverLevelValueName, &dwCrtFlags ) == FALSE )
  462. {
  463. dwExitCode = EXIT_CODE_ERROR;
  464. }
  465. else
  466. {
  467. if( ( dwCrtFlags != -1 ) &&
  468. ( ( dwCrtFlags & DRIVER_VERIFIER_IO_CHECKING ) != 0 ) )
  469. {
  470. //
  471. // DRIVER_VERIFIER_IO_CHECKING is set
  472. //
  473. bMmFlagIsSet = TRUE;
  474. }
  475. }
  476. RegCloseKey (MmKey);
  477. }
  478. if( dwExitCode != EXIT_CODE_ERROR && bMmFlagIsSet )
  479. {
  480. //
  481. // open the "I/O" key
  482. //
  483. lResult = RegOpenKeyEx (
  484. HKEY_LOCAL_MACHINE,
  485. RegIOVerifyKeyName,
  486. 0,
  487. KEY_QUERY_VALUE | KEY_WRITE,
  488. &IoKey);
  489. if (lResult != ERROR_SUCCESS)
  490. {
  491. if( lResult != ERROR_FILE_NOT_FOUND )
  492. {
  493. dwExitCode = EXIT_CODE_ERROR;
  494. if( lResult == ERROR_ACCESS_DENIED )
  495. {
  496. DisplayErrorMessage( IDS_ACCESS_IS_DENIED );
  497. }
  498. else
  499. {
  500. DisplayErrorMessage(
  501. IDS_REGOPENKEYEX_FAILED,
  502. RegIOVerifyKeyName,
  503. (DWORD)lResult);
  504. }
  505. }
  506. }
  507. else
  508. {
  509. //
  510. // read "I/O System\IoVerifierLevel" value
  511. //
  512. if( ReadRegistryValue( IoKey, RegIOVerifyLevelValueName, &dwCrtSysVerifLevel ) == FALSE )
  513. {
  514. dwExitCode = EXIT_CODE_ERROR;
  515. }
  516. RegCloseKey (IoKey);
  517. }
  518. }
  519. if( dwExitCode != EXIT_CODE_ERROR )
  520. {
  521. if( bMmFlagIsSet &&
  522. ( dwCrtSysVerifLevel == 2 || dwCrtSysVerifLevel == 3 ) )
  523. {
  524. DisplayErrorMessage(
  525. IDS_VERIFIER_ENABLED_FORMAT,
  526. dwCrtSysVerifLevel);
  527. }
  528. else
  529. {
  530. DisplayErrorMessage(
  531. IDS_VERIFIER_NOT_ENABLED_FORMAT );
  532. }
  533. }
  534. exit( dwExitCode );
  535. }
  536. //////////////////////////////////////////////////////////////////////
  537. //////////////////////////////// Local registry manipulation functions
  538. //////////////////////////////////////////////////////////////////////
  539. BOOL
  540. ReadRegistryValue (
  541. HKEY hKey,
  542. LPCTSTR Name,
  543. DWORD * Value)
  544. {
  545. LONG Result;
  546. DWORD Reserved;
  547. DWORD Type;
  548. DWORD Size;
  549. //
  550. // default value
  551. //
  552. *Value = -1;
  553. Size = sizeof( *Value );
  554. Result = RegQueryValueEx (
  555. hKey,
  556. Name,
  557. 0,
  558. &Type,
  559. (LPBYTE)(Value),
  560. &Size);
  561. //
  562. // Deal with a value that is not defined.
  563. //
  564. if (Result == ERROR_FILE_NOT_FOUND)
  565. {
  566. *Value = -1;
  567. return TRUE;
  568. }
  569. if (Result != ERROR_SUCCESS)
  570. {
  571. DisplayErrorMessage (
  572. IDS_REGQUERYVALUEEX_FAILED,
  573. Name,
  574. Result);
  575. return FALSE;
  576. }
  577. if (Type != REG_DWORD)
  578. {
  579. DisplayErrorMessage (
  580. IDS_REGQUERYVALUEEX_UNEXP_TYPE,
  581. Name);
  582. return FALSE;
  583. }
  584. if (Size != sizeof *Value)
  585. {
  586. DisplayErrorMessage (
  587. IDS_REGQUERYVALUEEX_UNEXP_SIZE,
  588. Name);
  589. return FALSE;
  590. }
  591. return TRUE;
  592. }
  593. BOOL
  594. WriteRegistryValue (
  595. HKEY hKey,
  596. LPCTSTR Name,
  597. DWORD Value)
  598. {
  599. LONG Result;
  600. Result = RegSetValueEx (
  601. hKey,
  602. Name,
  603. 0,
  604. REG_DWORD,
  605. (LPBYTE)(&Value),
  606. sizeof Value);
  607. if (Result != ERROR_SUCCESS)
  608. {
  609. DisplayErrorMessage (
  610. IDS_REGSETVALUEEX_FAILED,
  611. Name,
  612. Result);
  613. return FALSE;
  614. }
  615. return TRUE;
  616. }
  617. BOOL
  618. ReadRegistryString (
  619. HKEY hKey,
  620. LPCTSTR Name,
  621. LPTSTR Buffer,
  622. DWORD BufferSize )
  623. {
  624. LONG Result;
  625. DWORD Reserved;
  626. DWORD Type;
  627. DWORD Size;
  628. //
  629. // default value
  630. //
  631. *Buffer = 0;
  632. Size = BufferSize;
  633. Result = RegQueryValueEx (
  634. hKey,
  635. Name,
  636. 0,
  637. &Type,
  638. (LPBYTE)(Buffer),
  639. &Size);
  640. //
  641. // Deal with a value that is not defined.
  642. //
  643. if (Result == ERROR_FILE_NOT_FOUND)
  644. {
  645. *Buffer = 0;
  646. return TRUE;
  647. }
  648. if (Result != ERROR_SUCCESS)
  649. {
  650. DisplayErrorMessage (
  651. IDS_REGQUERYVALUEEX_FAILED,
  652. Name,
  653. Result);
  654. return FALSE;
  655. }
  656. if (Type != REG_SZ)
  657. {
  658. DisplayErrorMessage (
  659. IDS_REGQUERYVALUEEX_UNEXP_TYPE,
  660. Name);
  661. return FALSE;
  662. }
  663. return TRUE;
  664. }
  665. BOOL
  666. WriteRegistryString (
  667. HKEY hKey,
  668. LPCTSTR Name,
  669. LPTSTR Value)
  670. {
  671. LONG Result;
  672. DWORD Reserved;
  673. DWORD Type;
  674. Result = RegSetValueEx (
  675. hKey,
  676. Name,
  677. 0,
  678. REG_SZ,
  679. (LPBYTE)(Value),
  680. (_tcslen (Value) + 1) * sizeof (TCHAR));
  681. if (Result != ERROR_SUCCESS)
  682. {
  683. DisplayErrorMessage (
  684. IDS_REGSETVALUEEX_FAILED,
  685. Name,
  686. Result);
  687. return FALSE;
  688. }
  689. return TRUE;
  690. }
  691. BOOL
  692. IsKernelVerifierEnabled( HKEY MmKey )
  693. {
  694. BOOL bKernelVerified;
  695. int nKernelModuleNameLen;
  696. TCHAR *pstrCrtNameMatch, *pstrSubstring, *pCrtChar;
  697. TCHAR strVrfDriver [VRF_MAX_DRIVER_STRING_LENGTH];
  698. const TCHAR strKernelModuleName[] = _T( "ntoskrnl.exe" );
  699. bKernelVerified = FALSE;
  700. if( ReadRegistryString (MmKey, RegVerifyDriversValueName, strVrfDriver, sizeof( strVrfDriver ) ) )
  701. {
  702. pstrSubstring = _tcsstr( strVrfDriver, strKernelModuleName );
  703. if( pstrSubstring != NULL )
  704. {
  705. //
  706. // the name seems to be already there
  707. //
  708. pCrtChar = strVrfDriver;
  709. while( pCrtChar < pstrSubstring )
  710. {
  711. if( (*pCrtChar) != _T( ' ' ) && (*pCrtChar) != _T( '\t' ) )
  712. {
  713. //
  714. // non-blanc character before the name
  715. //
  716. break;
  717. }
  718. pCrtChar ++;
  719. }
  720. if( pCrtChar >= pstrSubstring )
  721. {
  722. //
  723. // the module name begins as the first non-blanc character
  724. //
  725. nKernelModuleNameLen = _tcsclen( strKernelModuleName );
  726. if( pstrSubstring[ nKernelModuleNameLen ] == (TCHAR)0 ||
  727. pstrSubstring[ nKernelModuleNameLen ] == _T( ' ' ) ||
  728. pstrSubstring[ nKernelModuleNameLen ] == _T( '\t' ) )
  729. {
  730. bKernelVerified = TRUE;
  731. }
  732. }
  733. }
  734. }
  735. return bKernelVerified;
  736. }