// // Driver Verifier UI // Copyright (c) Microsoft Corporation, 1999 // // // // module: VSetting.cpp // author: DMihai // created: 11/1/00 // // Description // // Implementation of the CVerifierSettings class. // #include "stdafx.h" #include "verifier.h" #include "VSetting.h" #include "VrfUtil.h" #include "VGlobal.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // CDriverData Class ////////////////////////////////////////////////////////////////////// CDriverData::CDriverData() { m_SignedStatus = SignedNotVerifiedYet; m_VerifyDriverStatus = VerifyDriverNo; } CDriverData::CDriverData( const CDriverData &DriverData ) { m_strName = DriverData.m_strName; m_SignedStatus = DriverData.m_SignedStatus; m_VerifyDriverStatus= DriverData.m_VerifyDriverStatus; } CDriverData::CDriverData( LPCTSTR szDriverName ) { m_SignedStatus = SignedNotVerifiedYet; m_VerifyDriverStatus = VerifyDriverNo; m_strName = szDriverName; } CDriverData::~CDriverData() { } ////////////////////////////////////////////////////////////////////// BOOL CDriverData::LoadDriverHeaderData() { // // N.B. // // The imagehlp functions are not multithreading safe // (see Whistler bug #88373) so if we want to use them from more than // one thread we will have to aquire some critical section before. // // Currently only one thread is using the imagehlp APIs in this app // (CSlowProgressDlg::LoadDriverDataWorkerThread) so we don't need // our synchronization. // LPTSTR szDriverName; LPTSTR szDriversDir; PLOADED_IMAGE pLoadedImage; BOOL bSuccess; BOOL bUnloaded; bSuccess = FALSE; ASSERT( m_strName.GetLength() > 0 ); // // ImageLoad doesn't know about const pointers so // we have to GetBuffer here :-( // szDriverName = m_strName.GetBuffer( m_strName.GetLength() + 1 ); if( NULL == szDriverName ) { goto Done; } szDriversDir = g_strDriversDir.GetBuffer( g_strDriversDir.GetLength() + 1 ); if( NULL == szDriversDir ) { m_strName.ReleaseBuffer(); goto Done; } // // Load the image // pLoadedImage = VrfImageLoad( szDriverName, szDriversDir ); if( NULL == pLoadedImage ) { // // Could not load the image from %windir%\system32\drivers // Try again from the PATH // pLoadedImage = VrfImageLoad( szDriverName, NULL ); } // // Give our string buffers back to MFC // m_strName.ReleaseBuffer(); g_strDriversDir.ReleaseBuffer(); if( NULL == pLoadedImage ) { // // We couldn't load this image - bad luck // TRACE( _T( "ImageLoad failed for %s, error %u\n" ), (LPCTSTR) m_strName, GetLastError() ); goto Done; } // // Keep the OS and image version information (4 means NT 4 etc.) // m_wMajorOperatingSystemVersion = pLoadedImage->FileHeader->OptionalHeader.MajorOperatingSystemVersion; m_wMajorImageVersion = pLoadedImage->FileHeader->OptionalHeader.MajorImageVersion; // // Check if the current driver is a miniport // VrfIsDriverMiniport( pLoadedImage, m_strMiniportName ); // // Clean-up // bUnloaded = ImageUnload( pLoadedImage ); // // If ImageUnload fails we cannot do much about it... // ASSERT( bUnloaded ); bSuccess = TRUE; Done: return bSuccess; } ////////////////////////////////////////////////////////////////////// BOOL CDriverData::LoadDriverVersionData() { BOOL bResult; PVOID pWholeVerBlock; PVOID pTranslationInfoBuffer; LPCTSTR szVariableValue; LPTSTR szDriverPath; DWORD dwWholeBlockSize; DWORD dwDummyHandle; UINT uInfoLengthInTChars; TCHAR szLocale[ 32 ]; TCHAR szBlockName[ 64 ]; CString strDriverPath; bResult = FALSE; // // Get the size of the file info block // // GetFileVersionInfoSize doesn't know about // const pointers so we need to GetBuffer here :-( // strDriverPath = g_strDriversDir + '\\' + m_strName; szDriverPath = strDriverPath.GetBuffer( strDriverPath.GetLength() + 1 ); if( NULL == szDriverPath ) { goto InitializeWithDefaults; } dwWholeBlockSize = GetFileVersionInfoSize( szDriverPath, &dwDummyHandle ); strDriverPath.ReleaseBuffer(); if( dwWholeBlockSize == 0 ) { // // Couldn't find the binary in %windir%\system32\drivers // Try %windir%\system32 too // strDriverPath = g_strSystemDir + '\\' + m_strName; szDriverPath = strDriverPath.GetBuffer( strDriverPath.GetLength() + 1 ); if( NULL == szDriverPath ) { goto InitializeWithDefaults; } dwWholeBlockSize = GetFileVersionInfoSize( szDriverPath, &dwDummyHandle ); strDriverPath.ReleaseBuffer(); if( dwWholeBlockSize == 0 ) { // // Couldn't read version information // goto InitializeWithDefaults; } } // // Allocate the buffer for the version information // pWholeVerBlock = malloc( dwWholeBlockSize ); if( pWholeVerBlock == NULL ) { goto InitializeWithDefaults; } // // Get the version information // // GetFileVersionInfo doesn't know about // const pointers so we need to GetBuffer here :-( // szDriverPath = strDriverPath.GetBuffer( strDriverPath.GetLength() + 1 ); if( NULL == szDriverPath ) { free( pWholeVerBlock ); goto InitializeWithDefaults; } bResult = GetFileVersionInfo( szDriverPath, dwDummyHandle, dwWholeBlockSize, pWholeVerBlock ); strDriverPath.ReleaseBuffer(); if( bResult != TRUE ) { free( pWholeVerBlock ); goto InitializeWithDefaults; } // // Get the locale info // bResult = VerQueryValue( pWholeVerBlock, _T( "\\VarFileInfo\\Translation" ), &pTranslationInfoBuffer, &uInfoLengthInTChars ); if( TRUE != bResult || NULL == pTranslationInfoBuffer ) { free( pWholeVerBlock ); goto InitializeWithDefaults; } // // Locale info comes back as two little endian words. // Flip 'em, 'cause we need them big endian for our calls. // _stprintf( szLocale, _T( "%02X%02X%02X%02X" ), HIBYTE( LOWORD ( * (LPDWORD) pTranslationInfoBuffer) ), LOBYTE( LOWORD ( * (LPDWORD) pTranslationInfoBuffer) ), HIBYTE( HIWORD ( * (LPDWORD) pTranslationInfoBuffer) ), LOBYTE( HIWORD ( * (LPDWORD) pTranslationInfoBuffer) ) ); // // Get the file version // _stprintf( szBlockName, _T( "\\StringFileInfo\\%s\\FileVersion" ), szLocale ); bResult = VerQueryValue( pWholeVerBlock, szBlockName, (PVOID*) &szVariableValue, &uInfoLengthInTChars ); if( TRUE != bResult || 0 == uInfoLengthInTChars ) { // // Couldn't find the version // VERIFY( m_strFileVersion.LoadString( IDS_UNKNOWN ) ); } else { // // Found the version // m_strFileVersion = szVariableValue; } // // Get the company name // _stprintf( szBlockName, _T( "\\StringFileInfo\\%s\\CompanyName" ), szLocale ); bResult = VerQueryValue( pWholeVerBlock, szBlockName, (PVOID*) &szVariableValue, &uInfoLengthInTChars ); if( TRUE != bResult || uInfoLengthInTChars == 0 ) { // // Coudln't find the company name // m_strCompanyName.LoadString( IDS_UNKNOWN ); } else { m_strCompanyName = szVariableValue; } // // Get the FileDescription // _stprintf( szBlockName, _T( "\\StringFileInfo\\%s\\FileDescription" ), szLocale ); bResult = VerQueryValue( pWholeVerBlock, szBlockName, (PVOID*) &szVariableValue, &uInfoLengthInTChars ); if( TRUE != bResult || uInfoLengthInTChars == 0 ) { // // Coudln't find the FileDescription // m_strFileDescription.LoadString( IDS_UNKNOWN ); } else { m_strFileDescription = szVariableValue; } // // clean-up // free( pWholeVerBlock ); goto Done; InitializeWithDefaults: m_strCompanyName.LoadString( IDS_UNKNOWN ); m_strFileVersion.LoadString( IDS_UNKNOWN ); m_strFileDescription.LoadString( IDS_UNKNOWN ); Done: // // We always return TRUE from this function because // the app will work fine without the version info - // it's just something that we would like to be able to display // return TRUE; } ////////////////////////////////////////////////////////////////////// BOOL CDriverData::LoadDriverImageData() { BOOL bResult1; BOOL bResult2; bResult1 = LoadDriverHeaderData(); bResult2 = LoadDriverVersionData(); return ( bResult1 && bResult2 ); } ////////////////////////////////////////////////////////////////////// void CDriverData::AssertValid() const { ASSERT( SignedNotVerifiedYet == m_SignedStatus || SignedYes == m_SignedStatus || SignedNo == m_SignedStatus ); ASSERT( VerifyDriverNo == m_VerifyDriverStatus || VerifyDriverYes == m_VerifyDriverStatus ); CObject::AssertValid(); } ////////////////////////////////////////////////////////////////////// // CDriverDataArray Class ////////////////////////////////////////////////////////////////////// CDriverDataArray::~CDriverDataArray() { DeleteAll(); } ////////////////////////////////////////////////////////////////////// VOID CDriverDataArray::DeleteAll() { INT_PTR nArraySize; CDriverData *pCrtDriverData; nArraySize = GetSize(); while( nArraySize > 0 ) { nArraySize -= 1; pCrtDriverData = GetAt( nArraySize ); ASSERT_VALID( pCrtDriverData ); delete pCrtDriverData; } RemoveAll(); } ////////////////////////////////////////////////////////////////////// CDriverData *CDriverDataArray::GetAt( INT_PTR nIndex ) const { return (CDriverData *)CObArray::GetAt( nIndex ); } ////////////////////////////////////////////////////////////////////// CDriverDataArray &CDriverDataArray::operator = (const CDriverDataArray &DriversDataArray) { INT_PTR nNewArraySize; CDriverData *pCopiedDriverData; CDriverData *pNewDriverData; DeleteAll(); nNewArraySize = DriversDataArray.GetSize(); while( nNewArraySize > 0 ) { nNewArraySize -= 1; pCopiedDriverData = DriversDataArray.GetAt( nNewArraySize ); ASSERT_VALID( pCopiedDriverData ); pNewDriverData = new CDriverData( *pCopiedDriverData ); if( NULL != pNewDriverData ) { ASSERT_VALID( pNewDriverData ); Add( pNewDriverData ); } else { VrfErrorResourceFormat( IDS_NOT_ENOUGH_MEMORY ); goto Done; } } Done: // // All done, assert that our data is consistent // ASSERT_VALID( this ); return *this; } ////////////////////////////////////////////////////////////////////// // CDriversSet Class ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CDriversSet::CDriversSet() { m_DriverSetType = DriversSetNotSigned; m_bDriverDataInitialized = FALSE; m_bUnsignedDriverDataInitialized = FALSE; } CDriversSet::~CDriversSet() { } ////////////////////////////////////////////////////////////////////// BOOL CDriversSet::FindUnsignedDrivers( HANDLE hAbortEvent, CVrfProgressCtrl &ProgressCtl) { INT_PTR nAllDriverNames; INT_PTR nCrtDriverName; DWORD dwWaitResult; BOOL bSigned; BOOL bChangedCurrentDirectory; CDriverData *pDriverData; ProgressCtl.SetRange32(0, 100); ProgressCtl.SetStep( 1 ); ProgressCtl.SetPos( 0 ); bChangedCurrentDirectory = FALSE; if( TRUE != m_bUnsignedDriverDataInitialized ) { ASSERT( TRUE == m_bDriverDataInitialized ); // // We are going to check all drivers's signature // so change directory to %windir%\system32\drivers first // bChangedCurrentDirectory = SetCurrentDirectory( g_strDriversDir ); if( TRUE != bChangedCurrentDirectory ) { VrfErrorResourceFormat( IDS_CANNOT_SET_CURRENT_DIRECTORY, (LPCTSTR) g_strDriversDir ); } // // The unsigned drivers data is not initialized yet. // Try to initialize it now. // nAllDriverNames = m_aDriverData.GetSize(); ProgressCtl.SetRange32(0, nAllDriverNames ); for( nCrtDriverName = 0; nCrtDriverName < nAllDriverNames; nCrtDriverName+=1 ) { if( NULL != hAbortEvent ) { // // Check if the thread has to die // dwWaitResult = WaitForSingleObject( hAbortEvent, 0 ); if( WAIT_OBJECT_0 == dwWaitResult ) { // // We have to die... // TRACE( _T( "CDriversSet::FindUnsignedDrivers : aborting at driver %d of %d\n" ), nCrtDriverName, nAllDriverNames ); goto Done; } } pDriverData = m_aDriverData.GetAt( nCrtDriverName ); ASSERT_VALID( pDriverData ); // // If we already checked the signature of this driver before // don't spend any more time on it - use the cached data // if( CDriverData::SignedNotVerifiedYet == pDriverData->m_SignedStatus ) { bSigned = IsDriverSigned( pDriverData->m_strName ); if( TRUE != bSigned ) { // // This driver is not signed // pDriverData->m_SignedStatus = CDriverData::SignedNo; } else { // // This driver is signed // pDriverData->m_SignedStatus = CDriverData::SignedYes; } } ProgressCtl.StepIt(); } m_bUnsignedDriverDataInitialized = TRUE; } Done: if( TRUE == bChangedCurrentDirectory ) { SetCurrentDirectory( g_strInitialCurrentDirectory ); } return m_bUnsignedDriverDataInitialized; } ////////////////////////////////////////////////////////////////////// BOOL CDriversSet::LoadAllDriversData( HANDLE hAbortEvent, CVrfProgressCtrl &ProgressCtl ) { ULONG uBufferSize; ULONG uCrtModule; PVOID pBuffer; INT nCrtModuleNameLength; INT nBackSlashIndex; INT_PTR nDrvDataIndex; NTSTATUS Status; LPTSTR szCrtModuleName; DWORD dwWaitResult; CString strCrModuleName; CDriverData *pDriverData; PRTL_PROCESS_MODULES Modules; ProgressCtl.SetPos( 0 ); ProgressCtl.SetRange32( 0, 100 ); ProgressCtl.SetStep( 1 ); m_aDriverData.DeleteAll(); if( TRUE != m_bDriverDataInitialized ) { for( uBufferSize = 0x10000; TRUE; uBufferSize += 0x1000) { // // Allocate a new buffer // pBuffer = new BYTE[ uBufferSize ]; if( NULL == pBuffer ) { goto Done; } // // Query the kernel // Status = NtQuerySystemInformation ( SystemModuleInformation, pBuffer, uBufferSize, NULL); if( ! NT_SUCCESS( Status ) ) { delete pBuffer; if (Status == STATUS_INFO_LENGTH_MISMATCH) { // // Try with a bigger buffer // continue; } else { // // Fatal error - we cannot query // VrfErrorResourceFormat( IDS_CANT_GET_ACTIVE_DRVLIST, Status ); goto Done; } } else { // // Got all the information we needed // break; } } Modules = (PRTL_PROCESS_MODULES)pBuffer; ProgressCtl.SetRange32(0, Modules->NumberOfModules ); for( uCrtModule = 0; uCrtModule < Modules->NumberOfModules; uCrtModule += 1 ) { // // Check if the user wants to abort this long file processing... // if( NULL != hAbortEvent ) { // // Check if the thread has to die // dwWaitResult = WaitForSingleObject( hAbortEvent, 0 ); if( WAIT_OBJECT_0 == dwWaitResult ) { // // We have to die... // TRACE( _T( "CDriversSet::LoadAllDriversData : aborting at driver %u of %u\n" ), uCrtModule, (ULONG) Modules->NumberOfModules ); delete pBuffer; goto Done; } } if( Modules->Modules[uCrtModule].ImageBase < g_pHighestUserAddress ) { // // This is a user-mode module - we don't care about it // ProgressCtl.StepIt(); continue; } // // Add this driver to our list // nCrtModuleNameLength = strlen( (const char*)&Modules->Modules[uCrtModule].FullPathName[0] ); szCrtModuleName = strCrModuleName.GetBuffer( nCrtModuleNameLength + 1 ); if( NULL == szCrtModuleName ) { VrfErrorResourceFormat( IDS_NOT_ENOUGH_MEMORY ); goto Done; } #ifdef UNICODE MultiByteToWideChar( CP_ACP, 0, (const char*)&Modules->Modules[uCrtModule].FullPathName[0], -1, szCrtModuleName, ( nCrtModuleNameLength + 1 ) * sizeof( TCHAR ) ); #else strcpy( szCrtModuleName, (const char*)&Modules->Modules[uCrtModule].FullPathName[0] ); #endif strCrModuleName.ReleaseBuffer(); // // Keep only the file name, without the path // // It turns out that NtQuerySystemInformation ( SystemModuleInformation ) // can return the path in several different formats // // E.g. // // \winnt\system32\ntoskrnl.exe // acpi.sys // \winnt\system32\drivers\battc.sys // \systemroot\system32\drivers\videoprt.sys // nBackSlashIndex = strCrModuleName.ReverseFind( _T( '\\' ) ); if( nBackSlashIndex > 0 ) { strCrModuleName = strCrModuleName.Right( nCrtModuleNameLength - nBackSlashIndex - 1 ); } // // Add a data entry for this driver // strCrModuleName.MakeLower(); nDrvDataIndex = AddNewDriverData( strCrModuleName ); // // Deal with the kernel and HAL differently // if( ( uCrtModule == 0 || uCrtModule == 1 ) && nDrvDataIndex >= 0) { pDriverData = m_aDriverData.GetAt( nDrvDataIndex ); ASSERT_VALID( pDriverData ); if( 0 == uCrtModule ) { // // This is the kernel // pDriverData->m_strReservedName = _T( "ntoskrnl.exe" ); } else { // // This is the kernel // pDriverData->m_strReservedName = _T( "hal.dll" ); } } ProgressCtl.StepIt(); } delete pBuffer; m_bDriverDataInitialized = TRUE; } Done: return m_bDriverDataInitialized; } ////////////////////////////////////////////////////////////////////// BOOL CDriversSet::ShouldDriverBeVerified( const CDriverData *pDriverData ) const { BOOL bResult; bResult = FALSE; switch( m_DriverSetType ) { case DriversSetNotSigned: bResult = ( CDriverData::SignedNo == pDriverData->m_SignedStatus ); break; case DriversSetOldOs: bResult = ( 0 != pDriverData->m_wMajorOperatingSystemVersion && 5 > pDriverData->m_wMajorOperatingSystemVersion ) || ( 0 != pDriverData->m_wMajorImageVersion && 5 > pDriverData->m_wMajorImageVersion ); break; case DriversSetAllDrivers: bResult = TRUE; break; case DriversSetCustom: bResult = ( CDriverData::VerifyDriverYes == pDriverData->m_VerifyDriverStatus ); break; default: // // Oops, how did we get here?!? // ASSERT( FALSE ); } return bResult; } ////////////////////////////////////////////////////////////////////// BOOL CDriversSet::ShouldVerifySomeDrivers( ) const { INT_PTR nDrivers; INT_PTR nCrtDriver; CDriverData *pDriverData; BOOL bShouldVerifySome; bShouldVerifySome = FALSE; nDrivers = m_aDriverData.GetSize(); for( nCrtDriver = 0; nCrtDriver < nDrivers; nCrtDriver += 1 ) { pDriverData = m_aDriverData.GetAt( nCrtDriver ); ASSERT_VALID( pDriverData ); if( ShouldDriverBeVerified( pDriverData ) ) { bShouldVerifySome = TRUE; break; } } return bShouldVerifySome; } ////////////////////////////////////////////////////////////////////// BOOL CDriversSet::GetDriversToVerify( CString &strDriversToVerify ) { INT_PTR nDriversNo; INT_PTR nCrtDriver; CDriverData *pCrtDrvData; if( DriversSetAllDrivers == m_DriverSetType ) { // // Verify all drivers // strDriversToVerify = _T( '*' ); } else { // // Parse all the drivers list and see which ones should be verified // strDriversToVerify = _T( "" ); nDriversNo = m_aDriverData.GetSize(); for( nCrtDriver = 0; nCrtDriver < nDriversNo; nCrtDriver += 1 ) { pCrtDrvData = m_aDriverData.GetAt( nCrtDriver ); ASSERT_VALID( pCrtDrvData ); if( ShouldDriverBeVerified( pCrtDrvData ) ) { if( pCrtDrvData->m_strReservedName.GetLength() > 0 ) { // // Kernel or HAL // VrfAddDriverNameNoDuplicates( pCrtDrvData->m_strReservedName, strDriversToVerify ); } else { // // Regular driver // VrfAddDriverNameNoDuplicates( pCrtDrvData->m_strName, strDriversToVerify ); } if( pCrtDrvData->m_strMiniportName.GetLength() > 0 ) { // // This is a miniport - auto-enable the corresponding driver // TRACE( _T( "Auto-enabling %s\n" ), pCrtDrvData->m_strMiniportName ); VrfAddDriverNameNoDuplicates( pCrtDrvData->m_strMiniportName, strDriversToVerify ); } } } } return TRUE; } ////////////////////////////////////////////////////////////////////// INT_PTR CDriversSet::AddNewDriverData( LPCTSTR szDriverName, BOOL bForceIfFileNotFound /*= FALSE*/) { INT_PTR nIndexInArray; CDriverData *pNewDriverData; BOOL bSuccess; ASSERT( IsDriverNameInList( szDriverName ) == FALSE ); nIndexInArray = -1; pNewDriverData = new CDriverData( szDriverName ); if( NULL != pNewDriverData ) { bSuccess = pNewDriverData->LoadDriverImageData(); if( FALSE != bForceIfFileNotFound || FALSE != bSuccess ) { TRY { nIndexInArray = m_aDriverData.Add( pNewDriverData ); } CATCH( CMemoryException, pMemException ) { VrfErrorResourceFormat( IDS_NOT_ENOUGH_MEMORY ); nIndexInArray = -1; // // Clean-up the allocation since we cannot add it to our list // delete pNewDriverData; } END_CATCH } else { // // Could not load driver version, OS version etc. // Bad luck, we will not show this driver anyway in the lists, etc. // delete pNewDriverData; } } return nIndexInArray; } ////////////////////////////////////////////////////////////////////// // // Is this driver name already in our list? // BOOL CDriversSet::IsDriverNameInList( LPCTSTR szDriverName ) { INT_PTR nDrivers; INT_PTR nCrtDriver; CDriverData *pCrtDriverData; BOOL bIsInList; bIsInList = FALSE; nDrivers = m_aDriverData.GetSize(); for( nCrtDriver = 0; nCrtDriver < nDrivers; nCrtDriver += 1 ) { pCrtDriverData = m_aDriverData.GetAt( nCrtDriver ); ASSERT_VALID( pCrtDriverData ); if( pCrtDriverData->m_strName.CompareNoCase( szDriverName ) == 0 ) { bIsInList = TRUE; break; } } return bIsInList; } ////////////////////////////////////////////////////////////////////// // // Operators // CDriversSet & CDriversSet::operator = (const CDriversSet &DriversSet) { m_DriverSetType = DriversSet.m_DriverSetType; m_aDriverData = DriversSet.m_aDriverData; m_bDriverDataInitialized = DriversSet.m_bDriverDataInitialized; m_bUnsignedDriverDataInitialized = DriversSet.m_bUnsignedDriverDataInitialized; ::CopyStringArray( DriversSet.m_astrNotInstalledDriversToVerify, m_astrNotInstalledDriversToVerify ); // // All done - assert that our data is consistent // ASSERT_VALID( this ); return *this; } ////////////////////////////////////////////////////////////////////// // // Overrides // void CDriversSet::AssertValid() const { ASSERT( DriversSetCustom == m_DriverSetType || DriversSetOldOs == m_DriverSetType || DriversSetNotSigned == m_DriverSetType || DriversSetAllDrivers== m_DriverSetType ); ASSERT( TRUE == m_bDriverDataInitialized || FALSE == m_bDriverDataInitialized ); ASSERT( TRUE == m_bUnsignedDriverDataInitialized || FALSE == m_bUnsignedDriverDataInitialized ); m_aDriverData.AssertValid(); m_astrNotInstalledDriversToVerify.AssertValid(); CObject::AssertValid(); } ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// // CSettingsBits Class ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CSettingsBits::CSettingsBits() { m_SettingsType = SettingsTypeTypical; } CSettingsBits::~CSettingsBits() { } ////////////////////////////////////////////////////////////////////// // // Operators // CSettingsBits & CSettingsBits::operator = (const CSettingsBits &SettingsBits) { m_SettingsType = SettingsBits.m_SettingsType; m_bSpecialPoolEnabled = SettingsBits.m_bSpecialPoolEnabled; m_bForceIrqlEnabled = SettingsBits.m_bForceIrqlEnabled; m_bLowResEnabled = SettingsBits.m_bLowResEnabled; m_bPoolTrackingEnabled = SettingsBits.m_bPoolTrackingEnabled; m_bIoEnabled = SettingsBits.m_bIoEnabled; m_bDeadlockDetectEnabled= SettingsBits.m_bDeadlockDetectEnabled; m_bDMAVerifEnabled = SettingsBits.m_bDMAVerifEnabled; m_bEnhIoEnabled = SettingsBits.m_bEnhIoEnabled; // // All done, assert that our data is consistent // ASSERT_VALID( this ); return *this; } ////////////////////////////////////////////////////////////////////// // // Overrides // void CSettingsBits::AssertValid() const { CObject::AssertValid(); } ////////////////////////////////////////////////////////////////////// VOID CSettingsBits::SetTypicalOnly() { m_SettingsType = SettingsTypeTypical; m_bSpecialPoolEnabled = TRUE; m_bForceIrqlEnabled = TRUE; m_bPoolTrackingEnabled = TRUE; m_bIoEnabled = TRUE; m_bDeadlockDetectEnabled= TRUE; m_bDMAVerifEnabled = TRUE; // // Low resource simulation // m_bLowResEnabled = FALSE; // // Extreme or spurious tests // m_bEnhIoEnabled = FALSE; } ////////////////////////////////////////////////////////////////////// VOID CSettingsBits::EnableTypicalTests( BOOL bEnable ) { ASSERT( SettingsTypeTypical == m_SettingsType || SettingsTypeCustom == m_SettingsType ); m_bSpecialPoolEnabled = ( FALSE != bEnable ); m_bForceIrqlEnabled = ( FALSE != bEnable ); m_bPoolTrackingEnabled = ( FALSE != bEnable ); m_bIoEnabled = ( FALSE != bEnable ); m_bDeadlockDetectEnabled= ( FALSE != bEnable ); m_bDMAVerifEnabled = ( FALSE != bEnable ); } ////////////////////////////////////////////////////////////////////// VOID CSettingsBits::EnableExcessiveTests( BOOL bEnable ) { m_bEnhIoEnabled = ( FALSE != bEnable ); } ////////////////////////////////////////////////////////////////////// VOID CSettingsBits::EnableLowResTests( BOOL bEnable ) { m_bLowResEnabled = ( FALSE != bEnable ); } ////////////////////////////////////////////////////////////////////// BOOL CSettingsBits::GetVerifierFlags( DWORD &dwVerifyFlags ) { dwVerifyFlags = 0; if( FALSE != m_bSpecialPoolEnabled ) { dwVerifyFlags |= DRIVER_VERIFIER_SPECIAL_POOLING; } if( FALSE != m_bForceIrqlEnabled ) { dwVerifyFlags |= DRIVER_VERIFIER_FORCE_IRQL_CHECKING; } if( FALSE != m_bLowResEnabled ) { dwVerifyFlags |= DRIVER_VERIFIER_INJECT_ALLOCATION_FAILURES; } if( FALSE != m_bPoolTrackingEnabled ) { dwVerifyFlags |= DRIVER_VERIFIER_TRACK_POOL_ALLOCATIONS; } if( FALSE != m_bIoEnabled ) { dwVerifyFlags |= DRIVER_VERIFIER_IO_CHECKING; } if( FALSE != m_bDeadlockDetectEnabled ) { dwVerifyFlags |= DRIVER_VERIFIER_DEADLOCK_DETECTION; } if( FALSE != m_bDMAVerifEnabled ) { dwVerifyFlags |= DRIVER_VERIFIER_DMA_VERIFIER; } if( FALSE != m_bEnhIoEnabled ) { dwVerifyFlags |= DRIVER_VERIFIER_ENHANCED_IO_CHECKING; } return TRUE; } ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// // CVerifierSettings Class ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CVerifierSettings::CVerifierSettings() { } CVerifierSettings::~CVerifierSettings() { } ////////////////////////////////////////////////////////////////////// CVerifierSettings &CVerifierSettings::operator = (const CVerifierSettings &VerifSettings) { m_SettingsBits = VerifSettings.m_SettingsBits; m_DriversSet = VerifSettings.m_DriversSet; // // All done - assert that our data is consistent // ASSERT_VALID( this ); return *this; } ////////////////////////////////////////////////////////////////////// BOOL CVerifierSettings::SaveToRegistry() { DWORD dwVerifyFlags; DWORD dwPrevFlags; BOOL bSuccess; CString strDriversToVerify; CString strPrevVerifiedDrivers; dwVerifyFlags = 0; // // Get the list of drivers to verify // bSuccess = m_DriversSet.GetDriversToVerify( strDriversToVerify ) && m_SettingsBits.GetVerifierFlags( dwVerifyFlags ); if( bSuccess ) { // // Have something to write to the registry // // // Try to get the old settings // dwPrevFlags = 0; VrfReadVerifierSettings( strPrevVerifiedDrivers, dwPrevFlags ); if( strDriversToVerify.CompareNoCase( strPrevVerifiedDrivers ) != 0 || dwVerifyFlags != dwPrevFlags ) { VrfWriteVerifierSettings( TRUE, strDriversToVerify, TRUE, dwVerifyFlags ); } else { VrfMesssageFromResource( IDS_NO_SETTINGS_WERE_CHANGED ); } } return bSuccess; } ////////////////////////////////////////////////////////////////////// // // Overrides // void CVerifierSettings::AssertValid() const { m_SettingsBits.AssertValid(); m_DriversSet.AssertValid(); CObject::AssertValid(); } ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// // // Runtime data - queried from the kernel // ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// // // class CRuntimeDriverData // CRuntimeDriverData::CRuntimeDriverData() { Loads = 0; Unloads = 0; CurrentPagedPoolAllocations = 0; CurrentNonPagedPoolAllocations = 0; PeakPagedPoolAllocations = 0; PeakNonPagedPoolAllocations = 0; PagedPoolUsageInBytes = 0; NonPagedPoolUsageInBytes = 0; PeakPagedPoolUsageInBytes = 0; PeakNonPagedPoolUsageInBytes = 0; } ////////////////////////////////////////////////////////////////////// // // class CRuntimeDriverDataArray // CRuntimeDriverDataArray::~CRuntimeDriverDataArray() { DeleteAll(); } ////////////////////////////////////////////////////////////////////// CRuntimeDriverData *CRuntimeDriverDataArray::GetAt( INT_PTR nIndex ) { CRuntimeDriverData *pRetVal = (CRuntimeDriverData *)CObArray::GetAt( nIndex ); ASSERT_VALID( pRetVal ); return pRetVal; } ////////////////////////////////////////////////////////////////////// VOID CRuntimeDriverDataArray::DeleteAll() { INT_PTR nArraySize; CRuntimeDriverData *pCrtDriverData; nArraySize = GetSize(); while( nArraySize > 0 ) { nArraySize -= 1; pCrtDriverData = GetAt( nArraySize ); ASSERT_VALID( pCrtDriverData ); delete pCrtDriverData; } RemoveAll(); } ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// // // class CRuntimeVerifierData // CRuntimeVerifierData::CRuntimeVerifierData() { FillWithDefaults(); } ////////////////////////////////////////////////////////////////////// VOID CRuntimeVerifierData::FillWithDefaults() { m_bSpecialPool = FALSE; m_bPoolTracking = FALSE; m_bForceIrql = FALSE; m_bIo = FALSE; m_bEnhIo = FALSE; m_bDeadlockDetect = FALSE; m_bDMAVerif = FALSE; m_bLowRes = FALSE; RaiseIrqls = 0; AcquireSpinLocks = 0; SynchronizeExecutions = 0; AllocationsAttempted = 0; AllocationsSucceeded = 0; AllocationsSucceededSpecialPool = 0; AllocationsWithNoTag; Trims = 0; AllocationsFailed = 0; AllocationsFailedDeliberately = 0; UnTrackedPool = 0; Level = 0; m_RuntimeDriverDataArray.DeleteAll(); } ////////////////////////////////////////////////////////////////////// BOOL CRuntimeVerifierData::IsDriverVerified( LPCTSTR szDriveName ) { CRuntimeDriverData *pCrtDriverData; INT_PTR nDrivers; BOOL bFound; bFound = FALSE; nDrivers = m_RuntimeDriverDataArray.GetSize(); while( nDrivers > 0 ) { nDrivers -= 1; pCrtDriverData = m_RuntimeDriverDataArray.GetAt( nDrivers ); ASSERT_VALID( pCrtDriverData ); if( 0 == pCrtDriverData->m_strName.CompareNoCase( szDriveName ) ) { bFound = TRUE; break; } } return bFound; }