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.

1196 lines
29 KiB

  1. //
  2. // Enable driver verifier support for ntoskrnl
  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 "RegUtil.hxx"
  21. #include "GenUtil.hxx"
  22. #define VRF_MAX_DRIVER_STRING_LENGTH 4196
  23. #define LEVEL2_IO_VERIFIER_ENABLED_VALUE 3
  24. //////////////////////////////////////////////////////////////////////
  25. ///////////////////////////////////////////////////// Registry Strings
  26. //////////////////////////////////////////////////////////////////////
  27. LPCTSTR RegMemoryManagementKeyName =
  28. TEXT ("System\\CurrentControlSet\\Control\\Session Manager\\Memory Management");
  29. LPCTSTR RegVerifyDriversValueName =
  30. TEXT ("VerifyDrivers");
  31. LPCTSTR RegVerifyDriverLevelValueName =
  32. TEXT ("VerifyDriverLevel");
  33. LPCTSTR RegIOVerifyKeyName =
  34. TEXT ("System\\CurrentControlSet\\Control\\Session Manager\\I/O System");
  35. LPCTSTR RegIOVerifySubKeyName =
  36. TEXT ("I/O System");
  37. LPCTSTR RegIOVerifyLevelValueName =
  38. TEXT ("IoVerifierLevel");
  39. LPCTSTR RegSessionManagerKeyName =
  40. TEXT ("System\\CurrentControlSet\\Control\\Session Manager");
  41. //////////////////////////////////////////////////////////////////////
  42. /////////////// Forward decl for local registry manipulation functions
  43. //////////////////////////////////////////////////////////////////////
  44. BOOL
  45. ReadRegistryValue (
  46. HKEY HKey,
  47. LPCTSTR Name,
  48. DWORD * Value);
  49. BOOL
  50. WriteRegistryValue (
  51. HKEY MmKey,
  52. LPCTSTR Name,
  53. DWORD Value);
  54. BOOL
  55. ReadMmString (
  56. HKEY MmKey,
  57. LPCTSTR Name,
  58. LPTSTR Value);
  59. BOOL
  60. WriteMmString (
  61. HKEY MmKey,
  62. LPCTSTR Name,
  63. LPTSTR Value);
  64. //////////////////////////////////////////////////////////////////////
  65. ///////////////////////////////////////////////////// Public functions
  66. //////////////////////////////////////////////////////////////////////
  67. void
  68. WriteVerifierKeys(
  69. BOOL bEnableKrnVerifier,
  70. DWORD dwNewVerifierFlags,
  71. DWORD dwNewIoLevel,
  72. TCHAR *strKernelModuleName )
  73. {
  74. HKEY MmKey = NULL;
  75. DWORD dwExitCode;
  76. DWORD dwCrtFlags;
  77. DWORD dwCrtIoLevel;
  78. BOOL bMustAppendName;
  79. BOOL bAlreadyInRegistry;
  80. LONG lOpenResult;
  81. int nKernelModuleNameLen;
  82. int nStringLen;
  83. TCHAR *pstrCrtNameMatch, *pstrSubstring, *pCrtChar;
  84. TCHAR strVrfDriver [VRF_MAX_DRIVER_STRING_LENGTH];
  85. TCHAR strVrfDriverNew [VRF_MAX_DRIVER_STRING_LENGTH];
  86. dwExitCode = EXIT_CODE_NOTHING_CHANGED;
  87. //
  88. // Open the Mm key
  89. //
  90. lOpenResult = RegOpenKeyEx (
  91. HKEY_LOCAL_MACHINE,
  92. RegMemoryManagementKeyName,
  93. 0,
  94. KEY_QUERY_VALUE | KEY_WRITE,
  95. &MmKey);
  96. if (lOpenResult != ERROR_SUCCESS)
  97. {
  98. //
  99. // fatal error
  100. //
  101. dwExitCode = EXIT_CODE_ERROR;
  102. if( lOpenResult == ERROR_ACCESS_DENIED )
  103. {
  104. DisplayMessage( IDS_ACCESS_IS_DENIED );
  105. }
  106. else
  107. {
  108. DisplayMessage(
  109. IDS_REGOPENKEYEX_FAILED,
  110. RegMemoryManagementKeyName,
  111. (DWORD)lOpenResult);
  112. }
  113. }
  114. if( dwExitCode != EXIT_CODE_ERROR != 0 )
  115. {
  116. //
  117. // the IO verifier will be enabled
  118. //
  119. if( dwNewIoLevel != 2 )
  120. {
  121. //
  122. // only levels 1 & 2 are supported
  123. //
  124. dwNewIoLevel = 1;
  125. }
  126. //
  127. // get the current IO level
  128. //
  129. if( GetIoVerificationLevel( &dwCrtIoLevel ) == FALSE )
  130. {
  131. //
  132. // fatal error
  133. //
  134. dwExitCode = EXIT_CODE_ERROR;
  135. }
  136. }
  137. if( dwExitCode != EXIT_CODE_ERROR )
  138. {
  139. if( ReadRegistryValue( MmKey, RegVerifyDriverLevelValueName, &dwCrtFlags ) == FALSE )
  140. {
  141. dwExitCode = EXIT_CODE_ERROR;
  142. }
  143. else
  144. {
  145. if( dwNewVerifierFlags != -1 )
  146. {
  147. //
  148. // have some new flags
  149. //
  150. //
  151. // modify the flags in registry
  152. //
  153. if( dwCrtFlags != dwNewVerifierFlags )
  154. {
  155. if( WriteRegistryValue( MmKey, RegVerifyDriverLevelValueName, dwNewVerifierFlags ) == FALSE )
  156. {
  157. dwExitCode = EXIT_CODE_ERROR;
  158. }
  159. else
  160. {
  161. dwExitCode = EXIT_CODE_REBOOT;
  162. }
  163. }
  164. if( dwExitCode != EXIT_CODE_ERROR )
  165. {
  166. if( ( dwNewVerifierFlags & DRIVER_VERIFIER_IO_CHECKING ) == 0 )
  167. {
  168. //
  169. // IO verification is not enabled - disable "level 2" value too
  170. //
  171. dwNewIoLevel = 1;
  172. }
  173. //
  174. // the IO verifier will be enabled
  175. //
  176. if( dwCrtIoLevel != dwNewIoLevel )
  177. {
  178. //
  179. // need to switch the IO verification level
  180. //
  181. if( SwitchIoVerificationLevel( dwNewIoLevel ) == TRUE )
  182. {
  183. dwExitCode = EXIT_CODE_REBOOT;
  184. }
  185. else
  186. {
  187. dwExitCode = EXIT_CODE_ERROR;
  188. }
  189. }
  190. }
  191. }
  192. }
  193. if( dwExitCode != EXIT_CODE_ERROR && bEnableKrnVerifier )
  194. {
  195. //
  196. // enable verifier for the kernel
  197. //
  198. if( ReadMmString (MmKey, RegVerifyDriversValueName, strVrfDriver) == FALSE)
  199. {
  200. dwExitCode = EXIT_CODE_ERROR;
  201. }
  202. else
  203. {
  204. bAlreadyInRegistry = IsModuleNameAlreadyInRegistry(
  205. strKernelModuleName,
  206. strVrfDriver );
  207. if( bAlreadyInRegistry == FALSE )
  208. {
  209. _tcscpy( strVrfDriverNew, strKernelModuleName );
  210. if( strVrfDriver[ 0 ] != (TCHAR)0 )
  211. {
  212. if( strVrfDriver[ 0 ] != _T( ' ' ) &&
  213. strVrfDriver[ 0 ] != _T( '\t' ) )
  214. {
  215. //
  216. // add a space first
  217. //
  218. _tcscat( strVrfDriverNew, _T( " " ) );
  219. }
  220. //
  221. // add the old verified drivers at the end
  222. //
  223. _tcscat( strVrfDriverNew, strVrfDriver );
  224. }
  225. //
  226. // write the value
  227. //
  228. if (WriteMmString (MmKey, RegVerifyDriversValueName, strVrfDriverNew) == FALSE)
  229. {
  230. dwExitCode = EXIT_CODE_ERROR;
  231. }
  232. else
  233. {
  234. dwExitCode = EXIT_CODE_REBOOT;
  235. }
  236. }
  237. }
  238. }
  239. RegCloseKey (MmKey);
  240. }
  241. if( EXIT_CODE_REBOOT == dwExitCode )
  242. {
  243. DisplayMessage( IDS_MUST_REBOOT );
  244. }
  245. else
  246. {
  247. if( EXIT_CODE_NOTHING_CHANGED == dwExitCode )
  248. {
  249. DisplayMessage( IDS_NOTHING_CHANGED );
  250. }
  251. }
  252. exit( dwExitCode );
  253. }
  254. ///////////////////////////////////////////////////////////////////
  255. void
  256. RemoveModuleNameFromRegistry(
  257. TCHAR *strKernelModuleName )
  258. {
  259. HKEY MmKey = NULL;
  260. DWORD dwExitCode;
  261. LONG lOpenResult;
  262. int nKernelModuleNameLen;
  263. int nStringLen;
  264. int nLeftToCopy;
  265. TCHAR *pstrCrtNameMatch, *pstrSubstring;
  266. TCHAR strVrfDriver [VRF_MAX_DRIVER_STRING_LENGTH];
  267. TCHAR strVrfDriverNew [VRF_MAX_DRIVER_STRING_LENGTH];
  268. dwExitCode = EXIT_CODE_NOTHING_CHANGED;
  269. //
  270. // Open the Mm key
  271. //
  272. lOpenResult = RegOpenKeyEx (
  273. HKEY_LOCAL_MACHINE,
  274. RegMemoryManagementKeyName,
  275. 0,
  276. KEY_QUERY_VALUE | KEY_WRITE,
  277. &MmKey);
  278. if (lOpenResult != ERROR_SUCCESS)
  279. {
  280. dwExitCode = EXIT_CODE_ERROR;
  281. if( lOpenResult == ERROR_ACCESS_DENIED )
  282. {
  283. DisplayMessage( IDS_ACCESS_IS_DENIED );
  284. }
  285. else
  286. {
  287. DisplayMessage(
  288. IDS_REGOPENKEYEX_FAILED,
  289. RegMemoryManagementKeyName,
  290. (DWORD)lOpenResult);
  291. }
  292. }
  293. else
  294. {
  295. if( ReadMmString (MmKey, RegVerifyDriversValueName, strVrfDriver) == FALSE)
  296. {
  297. dwExitCode = EXIT_CODE_ERROR;
  298. }
  299. else
  300. {
  301. pstrCrtNameMatch = strVrfDriver;
  302. do
  303. {
  304. pstrSubstring = _tcsstr( pstrCrtNameMatch, strKernelModuleName );
  305. if( pstrSubstring != NULL )
  306. {
  307. //
  308. // the name seems to be there
  309. //
  310. nKernelModuleNameLen = _tcsclen( strKernelModuleName );
  311. nStringLen = _tcsclen( pstrSubstring );
  312. if( nStringLen > nKernelModuleNameLen &&
  313. pstrSubstring[ nKernelModuleNameLen ] != _TEXT(' ') &&
  314. pstrSubstring[ nKernelModuleNameLen ] != _TEXT('\t') )
  315. {
  316. //
  317. // this is not our name, continue searching
  318. //
  319. pstrCrtNameMatch += nKernelModuleNameLen;
  320. }
  321. else
  322. {
  323. if( pstrSubstring != &strVrfDriver[ 0 ] &&
  324. (* (pstrSubstring - 1) ) != _TEXT(' ') &&
  325. (* (pstrSubstring - 1) ) != _TEXT('\t') )
  326. {
  327. //
  328. // this is not our name, continue searching
  329. //
  330. pstrCrtNameMatch += min( nKernelModuleNameLen, nStringLen );
  331. }
  332. else
  333. {
  334. //
  335. // kernel's module name is in the registry
  336. //
  337. strVrfDriverNew[0] = (TCHAR)0;
  338. _tcsncat(
  339. strVrfDriverNew,
  340. strVrfDriver,
  341. (size_t)(pstrSubstring - &strVrfDriver[0]) );
  342. nLeftToCopy = nStringLen - nKernelModuleNameLen;
  343. pstrSubstring += nKernelModuleNameLen;
  344. while( nLeftToCopy > 0 )
  345. {
  346. if( *pstrSubstring != _TEXT( ' ' ) &&
  347. *pstrSubstring != _TEXT( '\t' ) )
  348. {
  349. //
  350. // append what starts from here
  351. //
  352. _tcscat( strVrfDriverNew, pstrSubstring );
  353. break;
  354. }
  355. else
  356. {
  357. //
  358. // skip spaces
  359. //
  360. pstrSubstring ++;
  361. nLeftToCopy --;
  362. }
  363. }
  364. //
  365. // write the new value to the registry
  366. //
  367. if (WriteMmString (MmKey, RegVerifyDriversValueName, strVrfDriverNew) == FALSE)
  368. {
  369. dwExitCode = EXIT_CODE_ERROR;
  370. }
  371. else
  372. {
  373. dwExitCode = EXIT_CODE_REBOOT;
  374. }
  375. break;
  376. }
  377. }
  378. }
  379. }
  380. while( pstrSubstring != NULL );
  381. }
  382. RegCloseKey (MmKey);
  383. }
  384. if( EXIT_CODE_REBOOT == dwExitCode )
  385. {
  386. DisplayMessage( IDS_MUST_REBOOT );
  387. }
  388. else
  389. {
  390. if( EXIT_CODE_NOTHING_CHANGED == dwExitCode )
  391. {
  392. DisplayMessage( IDS_NOTHING_CHANGED );
  393. }
  394. }
  395. exit( dwExitCode );
  396. }
  397. //////////////////////////////////////////////////
  398. void
  399. DumpStatusFromRegistry(
  400. LPCTSTR strKernelModuleName )
  401. {
  402. HKEY MmKey = NULL;
  403. DWORD dwExitCode;
  404. LONG lOpenResult;
  405. DWORD dwCrtFlags;
  406. DWORD dwIoLevel;
  407. int nKernelModuleNameLen;
  408. int nStringLen;
  409. BOOL bKernelVerified;
  410. BOOL bIsModuleNameRegistry;
  411. TCHAR *pstrCrtNameMatch, *pstrSubstring, *pCrtChar;
  412. TCHAR strVrfDriver [VRF_MAX_DRIVER_STRING_LENGTH];
  413. dwExitCode = EXIT_CODE_NOTHING_CHANGED;
  414. bKernelVerified = FALSE;
  415. //
  416. // Open the Mm key
  417. //
  418. lOpenResult = RegOpenKeyEx (
  419. HKEY_LOCAL_MACHINE,
  420. RegMemoryManagementKeyName,
  421. 0,
  422. KEY_QUERY_VALUE,
  423. &MmKey);
  424. if (lOpenResult != ERROR_SUCCESS)
  425. {
  426. dwExitCode = EXIT_CODE_ERROR;
  427. if( lOpenResult == ERROR_ACCESS_DENIED )
  428. {
  429. DisplayMessage( IDS_ACCESS_IS_DENIED );
  430. }
  431. else
  432. {
  433. DisplayMessage(
  434. IDS_REGOPENKEYEX_FAILED,
  435. RegMemoryManagementKeyName,
  436. (DWORD)lOpenResult);
  437. }
  438. }
  439. else
  440. {
  441. if( ReadMmString (MmKey, RegVerifyDriversValueName, strVrfDriver) == FALSE)
  442. {
  443. dwExitCode = EXIT_CODE_ERROR;
  444. }
  445. else
  446. {
  447. bIsModuleNameRegistry = IsModuleNameAlreadyInRegistry(
  448. strKernelModuleName,
  449. strVrfDriver );
  450. if( bIsModuleNameRegistry == TRUE )
  451. {
  452. //
  453. // we have 'ntoskrnl.exe' in the registry
  454. //
  455. //
  456. // read the verification flags
  457. //
  458. if( ReadRegistryValue( MmKey, RegVerifyDriverLevelValueName, &dwCrtFlags ) == FALSE )
  459. {
  460. dwExitCode = EXIT_CODE_ERROR;
  461. }
  462. else
  463. {
  464. bKernelVerified = TRUE;
  465. if( dwCrtFlags != -1 )
  466. {
  467. if( ( dwCrtFlags & DRIVER_VERIFIER_IO_CHECKING ) != 0 )
  468. {
  469. //
  470. // the IO verification is enabled, check the IO verification level ( 1 or 2 )
  471. //
  472. if( GetIoVerificationLevel( &dwIoLevel ) == FALSE )
  473. {
  474. dwExitCode = EXIT_CODE_ERROR;
  475. }
  476. else
  477. {
  478. if( dwIoLevel != 2 )
  479. {
  480. //
  481. // only levels 1 & 2 are supported
  482. //
  483. dwIoLevel = 1;
  484. }
  485. DisplayMessage(
  486. IDS_VERIFIER_ENABLED_WITH_IO_FORMAT,
  487. strKernelModuleName,
  488. dwCrtFlags,
  489. dwIoLevel );
  490. }
  491. }
  492. else
  493. {
  494. //
  495. // the IO verification is not enabled
  496. //
  497. DisplayMessage(
  498. IDS_VERIFIER_ENABLED_FORMAT,
  499. strKernelModuleName,
  500. dwCrtFlags );
  501. }
  502. }
  503. else
  504. {
  505. DisplayMessage(
  506. IDS_VERIFIER_ENABLED_NOFLAGS_FORMAT,
  507. strKernelModuleName );
  508. }
  509. }
  510. }
  511. if( EXIT_CODE_NOTHING_CHANGED == dwExitCode && ! bKernelVerified )
  512. {
  513. DisplayMessage(
  514. IDS_VERIFIER_NOT_ENABLED_FORMAT,
  515. strKernelModuleName );
  516. }
  517. }
  518. RegCloseKey (MmKey);
  519. }
  520. exit( dwExitCode );
  521. }
  522. //////////////////////////////////////////////////////////////////////
  523. //////////////////////////////// Local registry manipulation functions
  524. //////////////////////////////////////////////////////////////////////
  525. BOOL
  526. ReadRegistryValue (
  527. HKEY HKey,
  528. LPCTSTR Name,
  529. DWORD * Value)
  530. {
  531. LONG Result;
  532. DWORD Reserved;
  533. DWORD Type;
  534. DWORD Size;
  535. //
  536. // default value
  537. //
  538. *Value = -1;
  539. Size = sizeof *Value;
  540. Result = RegQueryValueEx (
  541. HKey,
  542. Name,
  543. 0,
  544. &Type,
  545. (LPBYTE)(Value),
  546. &Size);
  547. //
  548. // Deal with a value that is not defined.
  549. //
  550. if (Result == ERROR_FILE_NOT_FOUND)
  551. {
  552. *Value = -1;
  553. return TRUE;
  554. }
  555. if (Result != ERROR_SUCCESS)
  556. {
  557. DisplayMessage (
  558. IDS_REGQUERYVALUEEX_FAILED,
  559. Name,
  560. (DWORD)Result);
  561. return FALSE;
  562. }
  563. if (Type != REG_DWORD)
  564. {
  565. DisplayMessage (
  566. IDS_REGQUERYVALUEEX_UNEXP_TYPE,
  567. Name);
  568. return FALSE;
  569. }
  570. if (Size != sizeof *Value)
  571. {
  572. DisplayMessage (
  573. IDS_REGQUERYVALUEEX_UNEXP_SIZE,
  574. Name);
  575. return FALSE;
  576. }
  577. return TRUE;
  578. }
  579. BOOL
  580. WriteRegistryValue (
  581. HKEY HKey,
  582. LPCTSTR Name,
  583. DWORD Value)
  584. {
  585. LONG Result;
  586. Result = RegSetValueEx (
  587. HKey,
  588. Name,
  589. 0,
  590. REG_DWORD,
  591. (LPBYTE)(&Value),
  592. sizeof Value);
  593. if (Result != ERROR_SUCCESS)
  594. {
  595. DisplayMessage (
  596. IDS_REGSETVALUEEX_FAILED,
  597. Name,
  598. (DWORD)Result);
  599. return FALSE;
  600. }
  601. return TRUE;
  602. }
  603. BOOL
  604. ReadMmString (
  605. HKEY MmKey,
  606. LPCTSTR Name,
  607. LPTSTR Value)
  608. {
  609. LONG Result;
  610. DWORD Reserved;
  611. DWORD Type;
  612. DWORD Size;
  613. //
  614. // default value
  615. //
  616. *Value = 0;
  617. Size = VRF_MAX_DRIVER_STRING_LENGTH;
  618. Result = RegQueryValueEx (
  619. MmKey,
  620. Name,
  621. 0,
  622. &Type,
  623. (LPBYTE)(Value),
  624. &Size);
  625. //
  626. // Deal with a value that is not defined.
  627. //
  628. if (Result == ERROR_FILE_NOT_FOUND)
  629. {
  630. *Value = 0;
  631. return TRUE;
  632. }
  633. if (Result != ERROR_SUCCESS)
  634. {
  635. DisplayMessage (
  636. IDS_REGQUERYVALUEEX_FAILED,
  637. Name,
  638. (DWORD)Result);
  639. return FALSE;
  640. }
  641. if (Type != REG_SZ)
  642. {
  643. DisplayMessage (
  644. IDS_REGQUERYVALUEEX_UNEXP_TYPE,
  645. Name);
  646. return FALSE;
  647. }
  648. return TRUE;
  649. }
  650. BOOL
  651. WriteMmString (
  652. HKEY MmKey,
  653. LPCTSTR Name,
  654. LPTSTR Value)
  655. {
  656. LONG Result;
  657. DWORD Reserved;
  658. DWORD Type;
  659. DWORD Size;
  660. Result = RegSetValueEx (
  661. MmKey,
  662. Name,
  663. 0,
  664. REG_SZ,
  665. (LPBYTE)(Value),
  666. (_tcslen (Value) + 1) * sizeof (TCHAR));
  667. if (Result != ERROR_SUCCESS)
  668. {
  669. DisplayMessage (
  670. IDS_REGSETVALUEEX_FAILED,
  671. Name,
  672. (DWORD)Result);
  673. return FALSE;
  674. }
  675. return TRUE;
  676. }
  677. //////////////////////////////////////////////////
  678. BOOL
  679. IsModuleNameAlreadyInRegistry(
  680. LPCTSTR strKernelModuleName,
  681. LPCTSTR strWholeString )
  682. {
  683. BOOL bAlreadyInRegistry;
  684. int nKernelNameLength;
  685. LPCTSTR strString;
  686. LPCTSTR strSubstring;
  687. TCHAR cBefore;
  688. nKernelNameLength = _tcslen( strKernelModuleName );
  689. //
  690. // let's assume 'ntoskrnl.exe" is not already in the registry
  691. //
  692. bAlreadyInRegistry = FALSE;
  693. //
  694. // parse the string that's already in the registry
  695. //
  696. strString = strWholeString;
  697. while( *strString != (TCHAR)0 )
  698. {
  699. strSubstring = _tcsstr( strString, strKernelModuleName );
  700. if( strSubstring != NULL )
  701. {
  702. //
  703. // the string from the registry includes "ntoskrnl.exe"
  704. //
  705. //
  706. // let's assume it's nothing like "xyzntoskrnl.exe", "ntoskrnl.exexyz", etc.
  707. //
  708. bAlreadyInRegistry = TRUE;
  709. //
  710. // look for a character before the current substring
  711. //
  712. if( strSubstring > strWholeString )
  713. {
  714. //
  715. // have at least one character before "ntoskrnl.exe" - look if it is blanc
  716. //
  717. cBefore = *( strSubstring - 1 );
  718. if( cBefore != _T( ' ' ) && cBefore != _T( '\t' ) )
  719. {
  720. //
  721. // the character before "ntoskrnl.exe" is non-blanc -> not the name we are searching for
  722. //
  723. bAlreadyInRegistry = FALSE;
  724. }
  725. }
  726. //
  727. // look for a character after the current substring
  728. //
  729. if( bAlreadyInRegistry == TRUE &&
  730. strSubstring[ nKernelNameLength ] != (TCHAR)0 &&
  731. strSubstring[ nKernelNameLength ] != _T( ' ' ) &&
  732. strSubstring[ nKernelNameLength ] != _T( '\t' ) )
  733. {
  734. //
  735. // have a non-blanc character after this substring -> not the name we are searching for
  736. //
  737. bAlreadyInRegistry = FALSE;
  738. }
  739. if( bAlreadyInRegistry == FALSE )
  740. {
  741. //
  742. // this is not a real occurence of the name we are serching for, go further on
  743. //
  744. strString = strSubstring + 1;
  745. }
  746. if( bAlreadyInRegistry == TRUE )
  747. {
  748. //
  749. // found it
  750. //
  751. break;
  752. }
  753. }
  754. else
  755. {
  756. //
  757. // the name is not there
  758. //
  759. break;
  760. }
  761. }
  762. return bAlreadyInRegistry;
  763. }
  764. //////////////////////////////////////////////////
  765. BOOL
  766. GetIoVerificationLevel(
  767. DWORD *pdwIoLevel )
  768. {
  769. LONG lResult;
  770. HKEY IoKey = NULL;
  771. DWORD dwCrtIoVerifLevel;
  772. BOOL bFatalError;
  773. bFatalError = FALSE;
  774. //
  775. // default value
  776. //
  777. *pdwIoLevel = 1;
  778. //
  779. // open the "I/O" key
  780. //
  781. lResult = RegOpenKeyEx (
  782. HKEY_LOCAL_MACHINE,
  783. RegIOVerifyKeyName,
  784. 0,
  785. KEY_QUERY_VALUE,
  786. &IoKey);
  787. if (lResult != ERROR_SUCCESS)
  788. {
  789. //
  790. // cannot open the IO key
  791. //
  792. if( lResult != ERROR_FILE_NOT_FOUND )
  793. {
  794. //
  795. // the IO key is there, but we cannot open it
  796. //
  797. if( lResult == ERROR_ACCESS_DENIED )
  798. {
  799. DisplayMessage( IDS_ACCESS_IS_DENIED );
  800. }
  801. else
  802. {
  803. DisplayMessage(
  804. IDS_REGOPENKEYEX_FAILED,
  805. RegIOVerifyKeyName,
  806. (DWORD)lResult);
  807. }
  808. bFatalError = TRUE;
  809. }
  810. // else - the IO key doesn't exist - use default value
  811. }
  812. else
  813. {
  814. //
  815. // read "I/O System\IoVerifierLevel" value
  816. //
  817. if( ReadRegistryValue( IoKey, RegIOVerifyLevelValueName, &dwCrtIoVerifLevel ) )
  818. {
  819. if( LEVEL2_IO_VERIFIER_ENABLED_VALUE == dwCrtIoVerifLevel )
  820. {
  821. //
  822. // we are at level 2 IO verification
  823. //
  824. *pdwIoLevel = 2;
  825. }
  826. }
  827. RegCloseKey (IoKey);
  828. }
  829. return ( ! bFatalError );
  830. }
  831. //////////////////////////////////////////////////
  832. BOOL
  833. SwitchIoVerificationLevel(
  834. DWORD dwNewIoLevel )
  835. {
  836. BOOL bFatalError;
  837. LONG lResult;
  838. HKEY IoKey = NULL;
  839. HKEY SmKey = NULL;
  840. bFatalError = FALSE;
  841. //
  842. // Open the "I/O System" key
  843. //
  844. lResult = RegOpenKeyEx (
  845. HKEY_LOCAL_MACHINE,
  846. RegIOVerifyKeyName,
  847. 0,
  848. KEY_QUERY_VALUE | KEY_WRITE,
  849. &IoKey);
  850. if( lResult != ERROR_SUCCESS )
  851. {
  852. if( dwNewIoLevel == 2 )
  853. {
  854. //
  855. // cannot open the IO key - maybe a fatal error - anyway, we will try to create it
  856. //
  857. bFatalError = TRUE;
  858. if( lResult == ERROR_ACCESS_DENIED )
  859. {
  860. //
  861. // access is denied - fatal error
  862. //
  863. DisplayMessage( IDS_ACCESS_IS_DENIED );
  864. }
  865. else
  866. {
  867. if( lResult == ERROR_FILE_NOT_FOUND )
  868. {
  869. //
  870. // the "I/O System" key doesn't exist, try to create it
  871. //
  872. //
  873. // open the "Session Manager" key
  874. //
  875. lResult = RegOpenKeyEx (
  876. HKEY_LOCAL_MACHINE,
  877. RegSessionManagerKeyName,
  878. 0,
  879. KEY_QUERY_VALUE | KEY_WRITE,
  880. &SmKey);
  881. if( lResult != ERROR_SUCCESS )
  882. {
  883. //
  884. // cannot open the "Session Manager" key - fatal error
  885. //
  886. DisplayMessage(
  887. IDS_REGOPENKEYEX_FAILED,
  888. RegSessionManagerKeyName,
  889. (DWORD)lResult);
  890. }
  891. else
  892. {
  893. //
  894. // create the "I/O System" key
  895. //
  896. lResult = RegCreateKeyEx(
  897. SmKey,
  898. RegIOVerifySubKeyName,
  899. 0,
  900. NULL,
  901. REG_OPTION_NON_VOLATILE,
  902. KEY_WRITE | KEY_QUERY_VALUE,
  903. NULL,
  904. &IoKey,
  905. NULL );
  906. if( lResult != ERROR_SUCCESS )
  907. {
  908. //
  909. // cannot create key - fatal error
  910. //
  911. DisplayMessage(
  912. IDS_REGCREATEKEYEX_FAILED,
  913. RegIOVerifySubKeyName,
  914. (DWORD)lResult);
  915. }
  916. else
  917. {
  918. //
  919. // key created - reset the error code
  920. //
  921. bFatalError = FALSE;
  922. }
  923. //
  924. // close the "Session Manager" key
  925. //
  926. lResult = RegCloseKey(
  927. SmKey );
  928. }
  929. }
  930. else
  931. {
  932. //
  933. // other error opening the "I/O System" key
  934. //
  935. DisplayMessage(
  936. IDS_REGOPENKEYEX_FAILED,
  937. RegIOVerifyKeyName,
  938. (DWORD)lResult);
  939. }
  940. }
  941. }
  942. else
  943. bFatalError = TRUE;
  944. //else
  945. // we don't actually need the key in this case, we just want to wipe out
  946. // the IO verification registry value
  947. //
  948. }
  949. if( bFatalError == FALSE )
  950. {
  951. if( dwNewIoLevel == 2 )
  952. {
  953. //
  954. // if we reached this point, we should have the IO key opened
  955. //
  956. //
  957. // enable level 2
  958. //
  959. if( WriteRegistryValue( IoKey, RegIOVerifyLevelValueName, LEVEL2_IO_VERIFIER_ENABLED_VALUE ) == FALSE )
  960. {
  961. //
  962. // cannot recover from this
  963. //
  964. bFatalError = TRUE;
  965. }
  966. }
  967. else
  968. {
  969. //
  970. // disable level 2
  971. //
  972. lResult = RegDeleteValue(
  973. IoKey,
  974. RegIOVerifyLevelValueName );
  975. if( lResult != ERROR_SUCCESS && lResult != ERROR_FILE_NOT_FOUND )
  976. {
  977. bFatalError = TRUE;
  978. DisplayMessage(
  979. IDS_REGDELETEVALUE_FAILED,
  980. RegIOVerifyLevelValueName,
  981. (DWORD)lResult);
  982. }
  983. RegCloseKey (IoKey);
  984. }
  985. }
  986. return ( ! bFatalError );
  987. }