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.

1570 lines
38 KiB

  1. //
  2. // Driver Verifier UI
  3. // Copyright (c) Microsoft Corporation, 1999
  4. //
  5. //
  6. //
  7. // module: VSetting.cpp
  8. // author: DMihai
  9. // created: 11/1/00
  10. //
  11. // Description
  12. //
  13. // Implementation of the CVerifierSettings class.
  14. //
  15. #include "stdafx.h"
  16. #include "verifier.h"
  17. #include "VSetting.h"
  18. #include "VrfUtil.h"
  19. #include "VGlobal.h"
  20. #ifdef _DEBUG
  21. #undef THIS_FILE
  22. static char THIS_FILE[]=__FILE__;
  23. #define new DEBUG_NEW
  24. #endif
  25. //////////////////////////////////////////////////////////////////////
  26. // CDriverData Class
  27. //////////////////////////////////////////////////////////////////////
  28. CDriverData::CDriverData()
  29. {
  30. m_SignedStatus = SignedNotVerifiedYet;
  31. m_VerifyDriverStatus = VerifyDriverNo;
  32. }
  33. CDriverData::CDriverData( const CDriverData &DriverData )
  34. {
  35. m_strName = DriverData.m_strName;
  36. m_SignedStatus = DriverData.m_SignedStatus;
  37. m_VerifyDriverStatus= DriverData.m_VerifyDriverStatus;
  38. }
  39. CDriverData::CDriverData( LPCTSTR szDriverName )
  40. {
  41. m_SignedStatus = SignedNotVerifiedYet;
  42. m_VerifyDriverStatus = VerifyDriverNo;
  43. m_strName = szDriverName;
  44. }
  45. CDriverData::~CDriverData()
  46. {
  47. }
  48. //////////////////////////////////////////////////////////////////////
  49. BOOL CDriverData::LoadDriverHeaderData()
  50. {
  51. //
  52. // N.B.
  53. //
  54. // The imagehlp functions are not multithreading safe
  55. // (see Whistler bug #88373) so if we want to use them from more than
  56. // one thread we will have to aquire some critical section before.
  57. //
  58. // Currently only one thread is using the imagehlp APIs in this app
  59. // (CSlowProgressDlg::LoadDriverDataWorkerThread) so we don't need
  60. // our synchronization.
  61. //
  62. LPTSTR szDriverName;
  63. LPTSTR szDriversDir;
  64. PLOADED_IMAGE pLoadedImage;
  65. BOOL bSuccess;
  66. BOOL bUnloaded;
  67. bSuccess = FALSE;
  68. ASSERT( m_strName.GetLength() > 0 );
  69. //
  70. // ImageLoad doesn't know about const pointers so
  71. // we have to GetBuffer here :-(
  72. //
  73. szDriverName = m_strName.GetBuffer( m_strName.GetLength() + 1 );
  74. if( NULL == szDriverName )
  75. {
  76. goto Done;
  77. }
  78. szDriversDir = g_strDriversDir.GetBuffer( g_strDriversDir.GetLength() + 1 );
  79. if( NULL == szDriversDir )
  80. {
  81. m_strName.ReleaseBuffer();
  82. goto Done;
  83. }
  84. //
  85. // Load the image
  86. //
  87. pLoadedImage = VrfImageLoad( szDriverName,
  88. szDriversDir );
  89. if( NULL == pLoadedImage )
  90. {
  91. //
  92. // Could not load the image from %windir%\system32\drivers
  93. // Try again from the PATH
  94. //
  95. pLoadedImage = VrfImageLoad( szDriverName,
  96. NULL );
  97. }
  98. //
  99. // Give our string buffers back to MFC
  100. //
  101. m_strName.ReleaseBuffer();
  102. g_strDriversDir.ReleaseBuffer();
  103. if( NULL == pLoadedImage )
  104. {
  105. //
  106. // We couldn't load this image - bad luck
  107. //
  108. TRACE( _T( "ImageLoad failed for %s, error %u\n" ),
  109. (LPCTSTR) m_strName,
  110. GetLastError() );
  111. goto Done;
  112. }
  113. //
  114. // Keep the OS and image version information (4 means NT 4 etc.)
  115. //
  116. m_wMajorOperatingSystemVersion =
  117. pLoadedImage->FileHeader->OptionalHeader.MajorOperatingSystemVersion;
  118. m_wMajorImageVersion =
  119. pLoadedImage->FileHeader->OptionalHeader.MajorImageVersion;
  120. //
  121. // Check if the current driver is a miniport
  122. //
  123. VrfIsDriverMiniport( pLoadedImage,
  124. m_strMiniportName );
  125. //
  126. // Clean-up
  127. //
  128. bUnloaded = ImageUnload( pLoadedImage );
  129. //
  130. // If ImageUnload fails we cannot do much about it...
  131. //
  132. ASSERT( bUnloaded );
  133. bSuccess = TRUE;
  134. Done:
  135. return bSuccess;
  136. }
  137. //////////////////////////////////////////////////////////////////////
  138. BOOL CDriverData::LoadDriverVersionData()
  139. {
  140. BOOL bResult;
  141. PVOID pWholeVerBlock;
  142. PVOID pTranslationInfoBuffer;
  143. LPCTSTR szVariableValue;
  144. LPTSTR szDriverPath;
  145. DWORD dwWholeBlockSize;
  146. DWORD dwDummyHandle;
  147. UINT uInfoLengthInTChars;
  148. TCHAR szLocale[ 32 ];
  149. TCHAR szBlockName[ 64 ];
  150. CString strDriverPath;
  151. bResult = FALSE;
  152. //
  153. // Get the size of the file info block
  154. //
  155. // GetFileVersionInfoSize doesn't know about
  156. // const pointers so we need to GetBuffer here :-(
  157. //
  158. strDriverPath = g_strDriversDir + '\\' + m_strName;
  159. szDriverPath = strDriverPath.GetBuffer( strDriverPath.GetLength() + 1 );
  160. if( NULL == szDriverPath )
  161. {
  162. goto InitializeWithDefaults;
  163. }
  164. dwWholeBlockSize = GetFileVersionInfoSize(
  165. szDriverPath,
  166. &dwDummyHandle );
  167. strDriverPath.ReleaseBuffer();
  168. if( dwWholeBlockSize == 0 )
  169. {
  170. //
  171. // Couldn't find the binary in %windir%\system32\drivers
  172. // Try %windir%\system32 too
  173. //
  174. strDriverPath = g_strSystemDir + '\\' + m_strName;
  175. szDriverPath = strDriverPath.GetBuffer( strDriverPath.GetLength() + 1 );
  176. if( NULL == szDriverPath )
  177. {
  178. goto InitializeWithDefaults;
  179. }
  180. dwWholeBlockSize = GetFileVersionInfoSize(
  181. szDriverPath,
  182. &dwDummyHandle );
  183. strDriverPath.ReleaseBuffer();
  184. if( dwWholeBlockSize == 0 )
  185. {
  186. //
  187. // Couldn't read version information
  188. //
  189. goto InitializeWithDefaults;
  190. }
  191. }
  192. //
  193. // Allocate the buffer for the version information
  194. //
  195. pWholeVerBlock = malloc( dwWholeBlockSize );
  196. if( pWholeVerBlock == NULL )
  197. {
  198. goto InitializeWithDefaults;
  199. }
  200. //
  201. // Get the version information
  202. //
  203. // GetFileVersionInfo doesn't know about
  204. // const pointers so we need to GetBuffer here :-(
  205. //
  206. szDriverPath = strDriverPath.GetBuffer( strDriverPath.GetLength() + 1 );
  207. if( NULL == szDriverPath )
  208. {
  209. free( pWholeVerBlock );
  210. goto InitializeWithDefaults;
  211. }
  212. bResult = GetFileVersionInfo(
  213. szDriverPath,
  214. dwDummyHandle,
  215. dwWholeBlockSize,
  216. pWholeVerBlock );
  217. strDriverPath.ReleaseBuffer();
  218. if( bResult != TRUE )
  219. {
  220. free( pWholeVerBlock );
  221. goto InitializeWithDefaults;
  222. }
  223. //
  224. // Get the locale info
  225. //
  226. bResult = VerQueryValue(
  227. pWholeVerBlock,
  228. _T( "\\VarFileInfo\\Translation" ),
  229. &pTranslationInfoBuffer,
  230. &uInfoLengthInTChars );
  231. if( TRUE != bResult || NULL == pTranslationInfoBuffer )
  232. {
  233. free( pWholeVerBlock );
  234. goto InitializeWithDefaults;
  235. }
  236. //
  237. // Locale info comes back as two little endian words.
  238. // Flip 'em, 'cause we need them big endian for our calls.
  239. //
  240. _stprintf(
  241. szLocale,
  242. _T( "%02X%02X%02X%02X" ),
  243. HIBYTE( LOWORD ( * (LPDWORD) pTranslationInfoBuffer) ),
  244. LOBYTE( LOWORD ( * (LPDWORD) pTranslationInfoBuffer) ),
  245. HIBYTE( HIWORD ( * (LPDWORD) pTranslationInfoBuffer) ),
  246. LOBYTE( HIWORD ( * (LPDWORD) pTranslationInfoBuffer) ) );
  247. //
  248. // Get the file version
  249. //
  250. _stprintf(
  251. szBlockName,
  252. _T( "\\StringFileInfo\\%s\\FileVersion" ),
  253. szLocale );
  254. bResult = VerQueryValue(
  255. pWholeVerBlock,
  256. szBlockName,
  257. (PVOID*) &szVariableValue,
  258. &uInfoLengthInTChars );
  259. if( TRUE != bResult || 0 == uInfoLengthInTChars )
  260. {
  261. //
  262. // Couldn't find the version
  263. //
  264. VERIFY( m_strFileVersion.LoadString( IDS_UNKNOWN ) );
  265. }
  266. else
  267. {
  268. //
  269. // Found the version
  270. //
  271. m_strFileVersion = szVariableValue;
  272. }
  273. //
  274. // Get the company name
  275. //
  276. _stprintf(
  277. szBlockName,
  278. _T( "\\StringFileInfo\\%s\\CompanyName" ),
  279. szLocale );
  280. bResult = VerQueryValue(
  281. pWholeVerBlock,
  282. szBlockName,
  283. (PVOID*) &szVariableValue,
  284. &uInfoLengthInTChars );
  285. if( TRUE != bResult || uInfoLengthInTChars == 0 )
  286. {
  287. //
  288. // Coudln't find the company name
  289. //
  290. m_strCompanyName.LoadString( IDS_UNKNOWN );
  291. }
  292. else
  293. {
  294. m_strCompanyName = szVariableValue;
  295. }
  296. //
  297. // Get the FileDescription
  298. //
  299. _stprintf(
  300. szBlockName,
  301. _T( "\\StringFileInfo\\%s\\FileDescription" ),
  302. szLocale );
  303. bResult = VerQueryValue(
  304. pWholeVerBlock,
  305. szBlockName,
  306. (PVOID*) &szVariableValue,
  307. &uInfoLengthInTChars );
  308. if( TRUE != bResult || uInfoLengthInTChars == 0 )
  309. {
  310. //
  311. // Coudln't find the FileDescription
  312. //
  313. m_strFileDescription.LoadString( IDS_UNKNOWN );
  314. }
  315. else
  316. {
  317. m_strFileDescription = szVariableValue;
  318. }
  319. //
  320. // clean-up
  321. //
  322. free( pWholeVerBlock );
  323. goto Done;
  324. InitializeWithDefaults:
  325. m_strCompanyName.LoadString( IDS_UNKNOWN );
  326. m_strFileVersion.LoadString( IDS_UNKNOWN );
  327. m_strFileDescription.LoadString( IDS_UNKNOWN );
  328. Done:
  329. //
  330. // We always return TRUE from this function because
  331. // the app will work fine without the version info -
  332. // it's just something that we would like to be able to display
  333. //
  334. return TRUE;
  335. }
  336. //////////////////////////////////////////////////////////////////////
  337. BOOL CDriverData::LoadDriverImageData()
  338. {
  339. BOOL bResult1;
  340. BOOL bResult2;
  341. bResult1 = LoadDriverHeaderData();
  342. bResult2 = LoadDriverVersionData();
  343. return ( bResult1 && bResult2 );
  344. }
  345. //////////////////////////////////////////////////////////////////////
  346. void CDriverData::AssertValid() const
  347. {
  348. ASSERT( SignedNotVerifiedYet == m_SignedStatus ||
  349. SignedYes == m_SignedStatus ||
  350. SignedNo == m_SignedStatus );
  351. ASSERT( VerifyDriverNo == m_VerifyDriverStatus ||
  352. VerifyDriverYes == m_VerifyDriverStatus );
  353. CObject::AssertValid();
  354. }
  355. //////////////////////////////////////////////////////////////////////
  356. // CDriverDataArray Class
  357. //////////////////////////////////////////////////////////////////////
  358. CDriverDataArray::~CDriverDataArray()
  359. {
  360. DeleteAll();
  361. }
  362. //////////////////////////////////////////////////////////////////////
  363. VOID CDriverDataArray::DeleteAll()
  364. {
  365. INT_PTR nArraySize;
  366. CDriverData *pCrtDriverData;
  367. nArraySize = GetSize();
  368. while( nArraySize > 0 )
  369. {
  370. nArraySize -= 1;
  371. pCrtDriverData = GetAt( nArraySize );
  372. ASSERT_VALID( pCrtDriverData );
  373. delete pCrtDriverData;
  374. }
  375. RemoveAll();
  376. }
  377. //////////////////////////////////////////////////////////////////////
  378. CDriverData *CDriverDataArray::GetAt( INT_PTR nIndex ) const
  379. {
  380. return (CDriverData *)CObArray::GetAt( nIndex );
  381. }
  382. //////////////////////////////////////////////////////////////////////
  383. CDriverDataArray &CDriverDataArray::operator = (const CDriverDataArray &DriversDataArray)
  384. {
  385. INT_PTR nNewArraySize;
  386. CDriverData *pCopiedDriverData;
  387. CDriverData *pNewDriverData;
  388. DeleteAll();
  389. nNewArraySize = DriversDataArray.GetSize();
  390. while( nNewArraySize > 0 )
  391. {
  392. nNewArraySize -= 1;
  393. pCopiedDriverData = DriversDataArray.GetAt( nNewArraySize );
  394. ASSERT_VALID( pCopiedDriverData );
  395. pNewDriverData = new CDriverData( *pCopiedDriverData );
  396. if( NULL != pNewDriverData )
  397. {
  398. ASSERT_VALID( pNewDriverData );
  399. Add( pNewDriverData );
  400. }
  401. else
  402. {
  403. VrfErrorResourceFormat( IDS_NOT_ENOUGH_MEMORY );
  404. goto Done;
  405. }
  406. }
  407. Done:
  408. //
  409. // All done, assert that our data is consistent
  410. //
  411. ASSERT_VALID( this );
  412. return *this;
  413. }
  414. //////////////////////////////////////////////////////////////////////
  415. // CDriversSet Class
  416. //////////////////////////////////////////////////////////////////////
  417. //////////////////////////////////////////////////////////////////////
  418. // Construction/Destruction
  419. //////////////////////////////////////////////////////////////////////
  420. CDriversSet::CDriversSet()
  421. {
  422. m_DriverSetType = DriversSetNotSigned;
  423. m_bDriverDataInitialized = FALSE;
  424. m_bUnsignedDriverDataInitialized = FALSE;
  425. }
  426. CDriversSet::~CDriversSet()
  427. {
  428. }
  429. //////////////////////////////////////////////////////////////////////
  430. BOOL CDriversSet::FindUnsignedDrivers( HANDLE hAbortEvent,
  431. CVrfProgressCtrl &ProgressCtl)
  432. {
  433. INT_PTR nAllDriverNames;
  434. INT_PTR nCrtDriverName;
  435. DWORD dwWaitResult;
  436. BOOL bSigned;
  437. BOOL bChangedCurrentDirectory;
  438. CDriverData *pDriverData;
  439. ProgressCtl.SetRange32(0, 100);
  440. ProgressCtl.SetStep( 1 );
  441. ProgressCtl.SetPos( 0 );
  442. bChangedCurrentDirectory = FALSE;
  443. if( TRUE != m_bUnsignedDriverDataInitialized )
  444. {
  445. ASSERT( TRUE == m_bDriverDataInitialized );
  446. //
  447. // We are going to check all drivers's signature
  448. // so change directory to %windir%\system32\drivers first
  449. //
  450. bChangedCurrentDirectory = SetCurrentDirectory( g_strDriversDir );
  451. if( TRUE != bChangedCurrentDirectory )
  452. {
  453. VrfErrorResourceFormat( IDS_CANNOT_SET_CURRENT_DIRECTORY,
  454. (LPCTSTR) g_strDriversDir );
  455. }
  456. //
  457. // The unsigned drivers data is not initialized yet.
  458. // Try to initialize it now.
  459. //
  460. nAllDriverNames = m_aDriverData.GetSize();
  461. ProgressCtl.SetRange32(0, nAllDriverNames );
  462. for( nCrtDriverName = 0; nCrtDriverName < nAllDriverNames; nCrtDriverName+=1 )
  463. {
  464. if( NULL != hAbortEvent )
  465. {
  466. //
  467. // Check if the thread has to die
  468. //
  469. dwWaitResult = WaitForSingleObject( hAbortEvent,
  470. 0 );
  471. if( WAIT_OBJECT_0 == dwWaitResult )
  472. {
  473. //
  474. // We have to die...
  475. //
  476. TRACE( _T( "CDriversSet::FindUnsignedDrivers : aborting at driver %d of %d\n" ),
  477. nCrtDriverName,
  478. nAllDriverNames );
  479. goto Done;
  480. }
  481. }
  482. pDriverData = m_aDriverData.GetAt( nCrtDriverName );
  483. ASSERT_VALID( pDriverData );
  484. //
  485. // If we already checked the signature of this driver before
  486. // don't spend any more time on it - use the cached data
  487. //
  488. if( CDriverData::SignedNotVerifiedYet == pDriverData->m_SignedStatus )
  489. {
  490. bSigned = IsDriverSigned( pDriverData->m_strName );
  491. if( TRUE != bSigned )
  492. {
  493. //
  494. // This driver is not signed
  495. //
  496. pDriverData->m_SignedStatus = CDriverData::SignedNo;
  497. }
  498. else
  499. {
  500. //
  501. // This driver is signed
  502. //
  503. pDriverData->m_SignedStatus = CDriverData::SignedYes;
  504. }
  505. }
  506. ProgressCtl.StepIt();
  507. }
  508. m_bUnsignedDriverDataInitialized = TRUE;
  509. }
  510. Done:
  511. if( TRUE == bChangedCurrentDirectory )
  512. {
  513. SetCurrentDirectory( g_strInitialCurrentDirectory );
  514. }
  515. return m_bUnsignedDriverDataInitialized;
  516. }
  517. //////////////////////////////////////////////////////////////////////
  518. BOOL CDriversSet::LoadAllDriversData( HANDLE hAbortEvent,
  519. CVrfProgressCtrl &ProgressCtl )
  520. {
  521. ULONG uBufferSize;
  522. ULONG uCrtModule;
  523. PVOID pBuffer;
  524. INT nCrtModuleNameLength;
  525. INT nBackSlashIndex;
  526. INT_PTR nDrvDataIndex;
  527. NTSTATUS Status;
  528. LPTSTR szCrtModuleName;
  529. DWORD dwWaitResult;
  530. CString strCrModuleName;
  531. CDriverData *pDriverData;
  532. PRTL_PROCESS_MODULES Modules;
  533. ProgressCtl.SetPos( 0 );
  534. ProgressCtl.SetRange32( 0, 100 );
  535. ProgressCtl.SetStep( 1 );
  536. m_aDriverData.DeleteAll();
  537. if( TRUE != m_bDriverDataInitialized )
  538. {
  539. for( uBufferSize = 0x10000; TRUE; uBufferSize += 0x1000)
  540. {
  541. //
  542. // Allocate a new buffer
  543. //
  544. pBuffer = new BYTE[ uBufferSize ];
  545. if( NULL == pBuffer )
  546. {
  547. goto Done;
  548. }
  549. //
  550. // Query the kernel
  551. //
  552. Status = NtQuerySystemInformation ( SystemModuleInformation,
  553. pBuffer,
  554. uBufferSize,
  555. NULL);
  556. if( ! NT_SUCCESS( Status ) )
  557. {
  558. delete pBuffer;
  559. if (Status == STATUS_INFO_LENGTH_MISMATCH)
  560. {
  561. //
  562. // Try with a bigger buffer
  563. //
  564. continue;
  565. }
  566. else
  567. {
  568. //
  569. // Fatal error - we cannot query
  570. //
  571. VrfErrorResourceFormat( IDS_CANT_GET_ACTIVE_DRVLIST,
  572. Status );
  573. goto Done;
  574. }
  575. }
  576. else
  577. {
  578. //
  579. // Got all the information we needed
  580. //
  581. break;
  582. }
  583. }
  584. Modules = (PRTL_PROCESS_MODULES)pBuffer;
  585. ProgressCtl.SetRange32(0, Modules->NumberOfModules );
  586. for( uCrtModule = 0; uCrtModule < Modules->NumberOfModules; uCrtModule += 1 )
  587. {
  588. //
  589. // Check if the user wants to abort this long file processing...
  590. //
  591. if( NULL != hAbortEvent )
  592. {
  593. //
  594. // Check if the thread has to die
  595. //
  596. dwWaitResult = WaitForSingleObject( hAbortEvent,
  597. 0 );
  598. if( WAIT_OBJECT_0 == dwWaitResult )
  599. {
  600. //
  601. // We have to die...
  602. //
  603. TRACE( _T( "CDriversSet::LoadAllDriversData : aborting at driver %u of %u\n" ),
  604. uCrtModule,
  605. (ULONG) Modules->NumberOfModules );
  606. delete pBuffer;
  607. goto Done;
  608. }
  609. }
  610. if( Modules->Modules[uCrtModule].ImageBase < g_pHighestUserAddress )
  611. {
  612. //
  613. // This is a user-mode module - we don't care about it
  614. //
  615. ProgressCtl.StepIt();
  616. continue;
  617. }
  618. //
  619. // Add this driver to our list
  620. //
  621. nCrtModuleNameLength = strlen( (const char*)&Modules->Modules[uCrtModule].FullPathName[0] );
  622. szCrtModuleName = strCrModuleName.GetBuffer( nCrtModuleNameLength + 1 );
  623. if( NULL == szCrtModuleName )
  624. {
  625. VrfErrorResourceFormat( IDS_NOT_ENOUGH_MEMORY );
  626. goto Done;
  627. }
  628. #ifdef UNICODE
  629. MultiByteToWideChar( CP_ACP,
  630. 0,
  631. (const char*)&Modules->Modules[uCrtModule].FullPathName[0],
  632. -1,
  633. szCrtModuleName,
  634. ( nCrtModuleNameLength + 1 ) * sizeof( TCHAR ) );
  635. #else
  636. strcpy( szCrtModuleName,
  637. (const char*)&Modules->Modules[uCrtModule].FullPathName[0] );
  638. #endif
  639. strCrModuleName.ReleaseBuffer();
  640. //
  641. // Keep only the file name, without the path
  642. //
  643. // It turns out that NtQuerySystemInformation ( SystemModuleInformation )
  644. // can return the path in several different formats
  645. //
  646. // E.g.
  647. //
  648. // \winnt\system32\ntoskrnl.exe
  649. // acpi.sys
  650. // \winnt\system32\drivers\battc.sys
  651. // \systemroot\system32\drivers\videoprt.sys
  652. //
  653. nBackSlashIndex = strCrModuleName.ReverseFind( _T( '\\' ) );
  654. if( nBackSlashIndex > 0 )
  655. {
  656. strCrModuleName = strCrModuleName.Right( nCrtModuleNameLength - nBackSlashIndex - 1 );
  657. }
  658. //
  659. // Add a data entry for this driver
  660. //
  661. strCrModuleName.MakeLower();
  662. nDrvDataIndex = AddNewDriverData( strCrModuleName );
  663. //
  664. // Deal with the kernel and HAL differently
  665. //
  666. if( ( uCrtModule == 0 || uCrtModule == 1 ) && nDrvDataIndex >= 0)
  667. {
  668. pDriverData = m_aDriverData.GetAt( nDrvDataIndex );
  669. ASSERT_VALID( pDriverData );
  670. if( 0 == uCrtModule )
  671. {
  672. //
  673. // This is the kernel
  674. //
  675. pDriverData->m_strReservedName = _T( "ntoskrnl.exe" );
  676. }
  677. else
  678. {
  679. //
  680. // This is the kernel
  681. //
  682. pDriverData->m_strReservedName = _T( "hal.dll" );
  683. }
  684. }
  685. ProgressCtl.StepIt();
  686. }
  687. delete pBuffer;
  688. m_bDriverDataInitialized = TRUE;
  689. }
  690. Done:
  691. return m_bDriverDataInitialized;
  692. }
  693. //////////////////////////////////////////////////////////////////////
  694. BOOL CDriversSet::ShouldDriverBeVerified( const CDriverData *pDriverData ) const
  695. {
  696. BOOL bResult;
  697. bResult = FALSE;
  698. switch( m_DriverSetType )
  699. {
  700. case DriversSetNotSigned:
  701. bResult = ( CDriverData::SignedNo == pDriverData->m_SignedStatus );
  702. break;
  703. case DriversSetOldOs:
  704. bResult = ( 0 != pDriverData->m_wMajorOperatingSystemVersion && 5 > pDriverData->m_wMajorOperatingSystemVersion ) ||
  705. ( 0 != pDriverData->m_wMajorImageVersion && 5 > pDriverData->m_wMajorImageVersion );
  706. break;
  707. case DriversSetAllDrivers:
  708. bResult = TRUE;
  709. break;
  710. case DriversSetCustom:
  711. bResult = ( CDriverData::VerifyDriverYes == pDriverData->m_VerifyDriverStatus );
  712. break;
  713. default:
  714. //
  715. // Oops, how did we get here?!?
  716. //
  717. ASSERT( FALSE );
  718. }
  719. return bResult;
  720. }
  721. //////////////////////////////////////////////////////////////////////
  722. BOOL CDriversSet::ShouldVerifySomeDrivers( ) const
  723. {
  724. INT_PTR nDrivers;
  725. INT_PTR nCrtDriver;
  726. CDriverData *pDriverData;
  727. BOOL bShouldVerifySome;
  728. bShouldVerifySome = FALSE;
  729. nDrivers = m_aDriverData.GetSize();
  730. for( nCrtDriver = 0; nCrtDriver < nDrivers; nCrtDriver += 1 )
  731. {
  732. pDriverData = m_aDriverData.GetAt( nCrtDriver );
  733. ASSERT_VALID( pDriverData );
  734. if( ShouldDriverBeVerified( pDriverData ) )
  735. {
  736. bShouldVerifySome = TRUE;
  737. break;
  738. }
  739. }
  740. return bShouldVerifySome;
  741. }
  742. //////////////////////////////////////////////////////////////////////
  743. BOOL CDriversSet::GetDriversToVerify( CString &strDriversToVerify )
  744. {
  745. INT_PTR nDriversNo;
  746. INT_PTR nCrtDriver;
  747. CDriverData *pCrtDrvData;
  748. if( DriversSetAllDrivers == m_DriverSetType )
  749. {
  750. //
  751. // Verify all drivers
  752. //
  753. strDriversToVerify = _T( '*' );
  754. }
  755. else
  756. {
  757. //
  758. // Parse all the drivers list and see which ones should be verified
  759. //
  760. strDriversToVerify = _T( "" );
  761. nDriversNo = m_aDriverData.GetSize();
  762. for( nCrtDriver = 0; nCrtDriver < nDriversNo; nCrtDriver += 1 )
  763. {
  764. pCrtDrvData = m_aDriverData.GetAt( nCrtDriver );
  765. ASSERT_VALID( pCrtDrvData );
  766. if( ShouldDriverBeVerified( pCrtDrvData ) )
  767. {
  768. if( pCrtDrvData->m_strReservedName.GetLength() > 0 )
  769. {
  770. //
  771. // Kernel or HAL
  772. //
  773. VrfAddDriverNameNoDuplicates( pCrtDrvData->m_strReservedName,
  774. strDriversToVerify );
  775. }
  776. else
  777. {
  778. //
  779. // Regular driver
  780. //
  781. VrfAddDriverNameNoDuplicates( pCrtDrvData->m_strName,
  782. strDriversToVerify );
  783. }
  784. if( pCrtDrvData->m_strMiniportName.GetLength() > 0 )
  785. {
  786. //
  787. // This is a miniport - auto-enable the corresponding driver
  788. //
  789. TRACE( _T( "Auto-enabling %s\n" ), pCrtDrvData->m_strMiniportName );
  790. VrfAddDriverNameNoDuplicates( pCrtDrvData->m_strMiniportName,
  791. strDriversToVerify );
  792. }
  793. }
  794. }
  795. }
  796. return TRUE;
  797. }
  798. //////////////////////////////////////////////////////////////////////
  799. INT_PTR CDriversSet::AddNewDriverData( LPCTSTR szDriverName, BOOL bForceIfFileNotFound /*= FALSE*/)
  800. {
  801. INT_PTR nIndexInArray;
  802. CDriverData *pNewDriverData;
  803. BOOL bSuccess;
  804. ASSERT( IsDriverNameInList( szDriverName ) == FALSE );
  805. nIndexInArray = -1;
  806. pNewDriverData = new CDriverData( szDriverName );
  807. if( NULL != pNewDriverData )
  808. {
  809. bSuccess = pNewDriverData->LoadDriverImageData();
  810. if( FALSE != bForceIfFileNotFound || FALSE != bSuccess )
  811. {
  812. TRY
  813. {
  814. nIndexInArray = m_aDriverData.Add( pNewDriverData );
  815. }
  816. CATCH( CMemoryException, pMemException )
  817. {
  818. VrfErrorResourceFormat( IDS_NOT_ENOUGH_MEMORY );
  819. nIndexInArray = -1;
  820. //
  821. // Clean-up the allocation since we cannot add it to our list
  822. //
  823. delete pNewDriverData;
  824. }
  825. END_CATCH
  826. }
  827. else
  828. {
  829. //
  830. // Could not load driver version, OS version etc.
  831. // Bad luck, we will not show this driver anyway in the lists, etc.
  832. //
  833. delete pNewDriverData;
  834. }
  835. }
  836. return nIndexInArray;
  837. }
  838. //////////////////////////////////////////////////////////////////////
  839. //
  840. // Is this driver name already in our list?
  841. //
  842. BOOL CDriversSet::IsDriverNameInList( LPCTSTR szDriverName )
  843. {
  844. INT_PTR nDrivers;
  845. INT_PTR nCrtDriver;
  846. CDriverData *pCrtDriverData;
  847. BOOL bIsInList;
  848. bIsInList = FALSE;
  849. nDrivers = m_aDriverData.GetSize();
  850. for( nCrtDriver = 0; nCrtDriver < nDrivers; nCrtDriver += 1 )
  851. {
  852. pCrtDriverData = m_aDriverData.GetAt( nCrtDriver );
  853. ASSERT_VALID( pCrtDriverData );
  854. if( pCrtDriverData->m_strName.CompareNoCase( szDriverName ) == 0 )
  855. {
  856. bIsInList = TRUE;
  857. break;
  858. }
  859. }
  860. return bIsInList;
  861. }
  862. //////////////////////////////////////////////////////////////////////
  863. //
  864. // Operators
  865. //
  866. CDriversSet & CDriversSet::operator = (const CDriversSet &DriversSet)
  867. {
  868. m_DriverSetType = DriversSet.m_DriverSetType;
  869. m_aDriverData = DriversSet.m_aDriverData;
  870. m_bDriverDataInitialized = DriversSet.m_bDriverDataInitialized;
  871. m_bUnsignedDriverDataInitialized = DriversSet.m_bUnsignedDriverDataInitialized;
  872. ::CopyStringArray(
  873. DriversSet.m_astrNotInstalledDriversToVerify,
  874. m_astrNotInstalledDriversToVerify );
  875. //
  876. // All done - assert that our data is consistent
  877. //
  878. ASSERT_VALID( this );
  879. return *this;
  880. }
  881. //////////////////////////////////////////////////////////////////////
  882. //
  883. // Overrides
  884. //
  885. void CDriversSet::AssertValid() const
  886. {
  887. ASSERT( DriversSetCustom == m_DriverSetType ||
  888. DriversSetOldOs == m_DriverSetType ||
  889. DriversSetNotSigned == m_DriverSetType ||
  890. DriversSetAllDrivers== m_DriverSetType );
  891. ASSERT( TRUE == m_bDriverDataInitialized ||
  892. FALSE == m_bDriverDataInitialized );
  893. ASSERT( TRUE == m_bUnsignedDriverDataInitialized ||
  894. FALSE == m_bUnsignedDriverDataInitialized );
  895. m_aDriverData.AssertValid();
  896. m_astrNotInstalledDriversToVerify.AssertValid();
  897. CObject::AssertValid();
  898. }
  899. //////////////////////////////////////////////////////////////////////
  900. //////////////////////////////////////////////////////////////////////
  901. //////////////////////////////////////////////////////////////////////
  902. // CSettingsBits Class
  903. //////////////////////////////////////////////////////////////////////
  904. //////////////////////////////////////////////////////////////////////
  905. // Construction/Destruction
  906. //////////////////////////////////////////////////////////////////////
  907. CSettingsBits::CSettingsBits()
  908. {
  909. m_SettingsType = SettingsTypeTypical;
  910. }
  911. CSettingsBits::~CSettingsBits()
  912. {
  913. }
  914. //////////////////////////////////////////////////////////////////////
  915. //
  916. // Operators
  917. //
  918. CSettingsBits & CSettingsBits::operator = (const CSettingsBits &SettingsBits)
  919. {
  920. m_SettingsType = SettingsBits.m_SettingsType;
  921. m_bSpecialPoolEnabled = SettingsBits.m_bSpecialPoolEnabled;
  922. m_bForceIrqlEnabled = SettingsBits.m_bForceIrqlEnabled;
  923. m_bLowResEnabled = SettingsBits.m_bLowResEnabled;
  924. m_bPoolTrackingEnabled = SettingsBits.m_bPoolTrackingEnabled;
  925. m_bIoEnabled = SettingsBits.m_bIoEnabled;
  926. m_bDeadlockDetectEnabled= SettingsBits.m_bDeadlockDetectEnabled;
  927. m_bDMAVerifEnabled = SettingsBits.m_bDMAVerifEnabled;
  928. m_bEnhIoEnabled = SettingsBits.m_bEnhIoEnabled;
  929. //
  930. // All done, assert that our data is consistent
  931. //
  932. ASSERT_VALID( this );
  933. return *this;
  934. }
  935. //////////////////////////////////////////////////////////////////////
  936. //
  937. // Overrides
  938. //
  939. void CSettingsBits::AssertValid() const
  940. {
  941. CObject::AssertValid();
  942. }
  943. //////////////////////////////////////////////////////////////////////
  944. VOID CSettingsBits::SetTypicalOnly()
  945. {
  946. m_SettingsType = SettingsTypeTypical;
  947. m_bSpecialPoolEnabled = TRUE;
  948. m_bForceIrqlEnabled = TRUE;
  949. m_bPoolTrackingEnabled = TRUE;
  950. m_bIoEnabled = TRUE;
  951. m_bDeadlockDetectEnabled= TRUE;
  952. m_bDMAVerifEnabled = TRUE;
  953. //
  954. // Low resource simulation
  955. //
  956. m_bLowResEnabled = FALSE;
  957. //
  958. // Extreme or spurious tests
  959. //
  960. m_bEnhIoEnabled = FALSE;
  961. }
  962. //////////////////////////////////////////////////////////////////////
  963. VOID CSettingsBits::EnableTypicalTests( BOOL bEnable )
  964. {
  965. ASSERT( SettingsTypeTypical == m_SettingsType ||
  966. SettingsTypeCustom == m_SettingsType );
  967. m_bSpecialPoolEnabled = ( FALSE != bEnable );
  968. m_bForceIrqlEnabled = ( FALSE != bEnable );
  969. m_bPoolTrackingEnabled = ( FALSE != bEnable );
  970. m_bIoEnabled = ( FALSE != bEnable );
  971. m_bDeadlockDetectEnabled= ( FALSE != bEnable );
  972. m_bDMAVerifEnabled = ( FALSE != bEnable );
  973. }
  974. //////////////////////////////////////////////////////////////////////
  975. VOID CSettingsBits::EnableExcessiveTests( BOOL bEnable )
  976. {
  977. m_bEnhIoEnabled = ( FALSE != bEnable );
  978. }
  979. //////////////////////////////////////////////////////////////////////
  980. VOID CSettingsBits::EnableLowResTests( BOOL bEnable )
  981. {
  982. m_bLowResEnabled = ( FALSE != bEnable );
  983. }
  984. //////////////////////////////////////////////////////////////////////
  985. BOOL CSettingsBits::GetVerifierFlags( DWORD &dwVerifyFlags )
  986. {
  987. dwVerifyFlags = 0;
  988. if( FALSE != m_bSpecialPoolEnabled )
  989. {
  990. dwVerifyFlags |= DRIVER_VERIFIER_SPECIAL_POOLING;
  991. }
  992. if( FALSE != m_bForceIrqlEnabled )
  993. {
  994. dwVerifyFlags |= DRIVER_VERIFIER_FORCE_IRQL_CHECKING;
  995. }
  996. if( FALSE != m_bLowResEnabled )
  997. {
  998. dwVerifyFlags |= DRIVER_VERIFIER_INJECT_ALLOCATION_FAILURES;
  999. }
  1000. if( FALSE != m_bPoolTrackingEnabled )
  1001. {
  1002. dwVerifyFlags |= DRIVER_VERIFIER_TRACK_POOL_ALLOCATIONS;
  1003. }
  1004. if( FALSE != m_bIoEnabled )
  1005. {
  1006. dwVerifyFlags |= DRIVER_VERIFIER_IO_CHECKING;
  1007. }
  1008. if( FALSE != m_bDeadlockDetectEnabled )
  1009. {
  1010. dwVerifyFlags |= DRIVER_VERIFIER_DEADLOCK_DETECTION;
  1011. }
  1012. if( FALSE != m_bDMAVerifEnabled )
  1013. {
  1014. dwVerifyFlags |= DRIVER_VERIFIER_DMA_VERIFIER;
  1015. }
  1016. if( FALSE != m_bEnhIoEnabled )
  1017. {
  1018. dwVerifyFlags |= DRIVER_VERIFIER_ENHANCED_IO_CHECKING;
  1019. }
  1020. return TRUE;
  1021. }
  1022. //////////////////////////////////////////////////////////////////////
  1023. //////////////////////////////////////////////////////////////////////
  1024. //////////////////////////////////////////////////////////////////////
  1025. // CVerifierSettings Class
  1026. //////////////////////////////////////////////////////////////////////
  1027. //////////////////////////////////////////////////////////////////////
  1028. // Construction/Destruction
  1029. //////////////////////////////////////////////////////////////////////
  1030. CVerifierSettings::CVerifierSettings()
  1031. {
  1032. }
  1033. CVerifierSettings::~CVerifierSettings()
  1034. {
  1035. }
  1036. //////////////////////////////////////////////////////////////////////
  1037. CVerifierSettings &CVerifierSettings::operator = (const CVerifierSettings &VerifSettings)
  1038. {
  1039. m_SettingsBits = VerifSettings.m_SettingsBits;
  1040. m_DriversSet = VerifSettings.m_DriversSet;
  1041. //
  1042. // All done - assert that our data is consistent
  1043. //
  1044. ASSERT_VALID( this );
  1045. return *this;
  1046. }
  1047. //////////////////////////////////////////////////////////////////////
  1048. BOOL CVerifierSettings::SaveToRegistry()
  1049. {
  1050. DWORD dwVerifyFlags;
  1051. DWORD dwPrevFlags;
  1052. BOOL bSuccess;
  1053. CString strDriversToVerify;
  1054. CString strPrevVerifiedDrivers;
  1055. dwVerifyFlags = 0;
  1056. //
  1057. // Get the list of drivers to verify
  1058. //
  1059. bSuccess = m_DriversSet.GetDriversToVerify( strDriversToVerify ) &&
  1060. m_SettingsBits.GetVerifierFlags( dwVerifyFlags );
  1061. if( bSuccess )
  1062. {
  1063. //
  1064. // Have something to write to the registry
  1065. //
  1066. //
  1067. // Try to get the old settings
  1068. //
  1069. dwPrevFlags = 0;
  1070. VrfReadVerifierSettings( strPrevVerifiedDrivers,
  1071. dwPrevFlags );
  1072. if( strDriversToVerify.CompareNoCase( strPrevVerifiedDrivers ) != 0 ||
  1073. dwVerifyFlags != dwPrevFlags )
  1074. {
  1075. VrfWriteVerifierSettings( TRUE,
  1076. strDriversToVerify,
  1077. TRUE,
  1078. dwVerifyFlags );
  1079. }
  1080. else
  1081. {
  1082. VrfMesssageFromResource( IDS_NO_SETTINGS_WERE_CHANGED );
  1083. }
  1084. }
  1085. return bSuccess;
  1086. }
  1087. //////////////////////////////////////////////////////////////////////
  1088. //
  1089. // Overrides
  1090. //
  1091. void CVerifierSettings::AssertValid() const
  1092. {
  1093. m_SettingsBits.AssertValid();
  1094. m_DriversSet.AssertValid();
  1095. CObject::AssertValid();
  1096. }
  1097. //////////////////////////////////////////////////////////////////////
  1098. //////////////////////////////////////////////////////////////////////
  1099. //////////////////////////////////////////////////////////////////////
  1100. //
  1101. // Runtime data - queried from the kernel
  1102. //
  1103. //////////////////////////////////////////////////////////////////////
  1104. //////////////////////////////////////////////////////////////////////
  1105. //////////////////////////////////////////////////////////////////////
  1106. //////////////////////////////////////////////////////////////////////
  1107. //
  1108. // class CRuntimeDriverData
  1109. //
  1110. CRuntimeDriverData::CRuntimeDriverData()
  1111. {
  1112. Loads = 0;
  1113. Unloads = 0;
  1114. CurrentPagedPoolAllocations = 0;
  1115. CurrentNonPagedPoolAllocations = 0;
  1116. PeakPagedPoolAllocations = 0;
  1117. PeakNonPagedPoolAllocations = 0;
  1118. PagedPoolUsageInBytes = 0;
  1119. NonPagedPoolUsageInBytes = 0;
  1120. PeakPagedPoolUsageInBytes = 0;
  1121. PeakNonPagedPoolUsageInBytes = 0;
  1122. }
  1123. //////////////////////////////////////////////////////////////////////
  1124. //
  1125. // class CRuntimeDriverDataArray
  1126. //
  1127. CRuntimeDriverDataArray::~CRuntimeDriverDataArray()
  1128. {
  1129. DeleteAll();
  1130. }
  1131. //////////////////////////////////////////////////////////////////////
  1132. CRuntimeDriverData *CRuntimeDriverDataArray::GetAt( INT_PTR nIndex )
  1133. {
  1134. CRuntimeDriverData *pRetVal = (CRuntimeDriverData *)CObArray::GetAt( nIndex );
  1135. ASSERT_VALID( pRetVal );
  1136. return pRetVal;
  1137. }
  1138. //////////////////////////////////////////////////////////////////////
  1139. VOID CRuntimeDriverDataArray::DeleteAll()
  1140. {
  1141. INT_PTR nArraySize;
  1142. CRuntimeDriverData *pCrtDriverData;
  1143. nArraySize = GetSize();
  1144. while( nArraySize > 0 )
  1145. {
  1146. nArraySize -= 1;
  1147. pCrtDriverData = GetAt( nArraySize );
  1148. ASSERT_VALID( pCrtDriverData );
  1149. delete pCrtDriverData;
  1150. }
  1151. RemoveAll();
  1152. }
  1153. //////////////////////////////////////////////////////////////////////
  1154. //////////////////////////////////////////////////////////////////////
  1155. //
  1156. // class CRuntimeVerifierData
  1157. //
  1158. CRuntimeVerifierData::CRuntimeVerifierData()
  1159. {
  1160. FillWithDefaults();
  1161. }
  1162. //////////////////////////////////////////////////////////////////////
  1163. VOID CRuntimeVerifierData::FillWithDefaults()
  1164. {
  1165. m_bSpecialPool = FALSE;
  1166. m_bPoolTracking = FALSE;
  1167. m_bForceIrql = FALSE;
  1168. m_bIo = FALSE;
  1169. m_bEnhIo = FALSE;
  1170. m_bDeadlockDetect = FALSE;
  1171. m_bDMAVerif = FALSE;
  1172. m_bLowRes = FALSE;
  1173. RaiseIrqls = 0;
  1174. AcquireSpinLocks = 0;
  1175. SynchronizeExecutions = 0;
  1176. AllocationsAttempted = 0;
  1177. AllocationsSucceeded = 0;
  1178. AllocationsSucceededSpecialPool = 0;
  1179. AllocationsWithNoTag;
  1180. Trims = 0;
  1181. AllocationsFailed = 0;
  1182. AllocationsFailedDeliberately = 0;
  1183. UnTrackedPool = 0;
  1184. Level = 0;
  1185. m_RuntimeDriverDataArray.DeleteAll();
  1186. }
  1187. //////////////////////////////////////////////////////////////////////
  1188. BOOL CRuntimeVerifierData::IsDriverVerified( LPCTSTR szDriveName )
  1189. {
  1190. CRuntimeDriverData *pCrtDriverData;
  1191. INT_PTR nDrivers;
  1192. BOOL bFound;
  1193. bFound = FALSE;
  1194. nDrivers = m_RuntimeDriverDataArray.GetSize();
  1195. while( nDrivers > 0 )
  1196. {
  1197. nDrivers -= 1;
  1198. pCrtDriverData = m_RuntimeDriverDataArray.GetAt( nDrivers );
  1199. ASSERT_VALID( pCrtDriverData );
  1200. if( 0 == pCrtDriverData->m_strName.CompareNoCase( szDriveName ) )
  1201. {
  1202. bFound = TRUE;
  1203. break;
  1204. }
  1205. }
  1206. return bFound;
  1207. }